八、为什么程序员无法分清万圣节和圣诞节

1. 整形提升是指char,short int和位段类型(无论signed或unsigned)以及枚举类型将被提升为int或unsigned int(如果int能够完整容纳原先的数据,则提升为int,否则为unsigned int).如果编译器能够保证运算结果一致,也可以省略类型提升。

2. C语言中参数传递也可能发生隐式类型转换。如果使用了适当的函数原型,类型提升便不会发生,否则也会发生。在被调用函数的内部,提升后的参数被裁减为原先声明的大小。

3. C语言中的隐式类型转换起源于简化最初的编译器的想法。把所有的操作数转换为同一的长度极大地简化了代码的生成。这样,压到堆栈中的参数都是同一长度的,所以运行时系统只需要知道参数的数目,不需要知道它们的长度。

九、再论数组

1. 数组和指针等同的情况:

(1) 表达式中的数组名被编译器当作一个指向该数组第一个元素的指针。

类似加法,取下标操作符的操作数是可以交换的,所以在一个a[10]的声明中使用a[6]和6[a]都是正确的,因为编译器都将其解释为(a+6)。

(2) 数组下标总是与指针的偏移量相同。

(3) 在函数参数的声明中,数组名被编译器当作指向该数组第一个元素的指针。

把作为参数的数组和指针等同起来是出于效率的考虑,毕竟传址调用比拷贝整个数组效率更高。注意此时在函数内部不能通过sizeof来获取数组长度,因为数组已转换为指针。

2. 数组名是不可修改的左值,而指针的值可以修改。

 void func(int arr1[])
{
int arr2[] = {,,};
int arr3[] = {,,};
arr1 = arr2; // ok, arr1 has been converted to a pointer.
arr3 = arr2; // error, array's name is a left-value which can't be changed.
}

3. C语言中的数组就是一维数组,C语言的“多维数组”实际上是数组的数组。

4. 指针所指向的数组的维数不同,其自增操作的结果也不同。

 int parrot[][][];
int (*r)[] = parrot[]; // ++r将偏移4*5=20个字节
int *t = parrot[][]; // ++t将偏移4个字节

5. 对数组进行初始化时,如果数组的长度比所提供的初始化的个数要多,剩余的几个元素会被自动设置为0(若元素为int型)、空格(若元素为char型)、0.0(若元素为double型)、NULL(若元素为指针型).若声明数组时不提供任何初始值,则数组中的元素的值是未确定的。(在vc6.0环境下未初始化的int或指针取值均为0xcccccccc)。注意未初始化的指针的值并非NULL!

十、再论指针

1. “数组名被改写为一个指针参数”的规则并不是递归定义的,数组的数组会被编译器改写为“数组的指针”,而不是“指针的指针”。

     实参                                      所匹配的形参
char c[][]; /*数组的数组*/ char (*c)[]; /*数组指针*/
char *c[]; /*指针数组*/ char **c; /*指针的指针*/
char (*c)[]; /*数组指针*/ char (*c)[]; /*不改变*/
char **c; /*指针的指针*/ char **c; /*不改变*/

2. 使用指针向函数传递一个多维数组。比如:把array[x][y]改写为一个一维数组array[x+1],其元素类型是指向array[y]的指针,并在数组最后的那个元素array[x]里存储一个NULL指针,以提示数组的结束。

3. C语言中不能用const int常量来定义数组的长度,C++则可以。

 const int SIZE = ;
char plum[SIZE]; // error in C, ok in C++

4. 库函数realloc()能够对一个现在的内存块大小进行重新分配,同时不会丢失原先内存块的内容。在实践中,不要把realloc()函数的返回值直接赋给字符指针,如果realloc()函数失败,它会使该指针的值变为NULL,导致无法对现有的表进行访问。

十一、你懂得C,所以C++不在话下

1. C语言允许用户定义新的类型(struct, enum)来支持抽象,但C语言不允许在用户定义类型中重新定义*,<<,[],+等预定义操作符,而C++则允许。

2. C++同时提供自动和受控制的初始化、数据在生命期结束后自动消除以及隐式类型转换。这些特性有些是C语言不支持的,有些在C语言里不是很方便。(?)

3. C语言没有完备的机制来实现封装。

封装即把数据和相关的操作捆绑在一起,具体说是把用户定义的数据结构和用户定义的能够在这些数据结构上进行操作的函数捆绑在一起实现了数据的完整性,别的函数无法访问用户定义类型的内部数据或操作。C语言允许程序员把各种数据类型组合在一起形成自定义的记录(结构体),但无法对函数进行限制。如果一个结构是完全可见的,其任何部分都可能以任何方式被修改。人们无法把函数固定在数据类型上,使它们清晰地融为一体。

4. 类型转换

int i = ;
float x = (float)i; // C style
float y = float(i); // C++ style

5. 在C语言中,一个语句块中所有的声明都必须放在所有语句的前面,在C++中声明可以出现在语句可以出现的任何地方。

6. 在C++中,一个内层作用域的结构名将会隐藏外层空间中相同的对象名,在C语言中则并非如此。

7. 在C++中字符常量的类型是char,在C语言中字符常量的类型是int。即在C++中,sizeof('a') = 1;在C语言中,sizeof('a') = 4.(假设sizeof(int) = 4)。

8. 由于C++中增加了新的注释符//,有时会在两种语言中产生微妙而怪异的差别。

9. 在C++中存在,但在C语言中却不存在的限制有:

(1) 在C++中用户代码不能调用main()函数,在C语言中这是运行的(尽管这种情况很罕见)。

(2) 完整的函数原型声明在C++中是必须的,在C语言中则没这么严格。

(3) 在C++中由typedef定义的名字不能与已有的结构标签冲突,在C语言中这是允许的(它们分属不同的名字空间)。

(4) 当void*指针赋值给另一个类型的指针时,C++规定必须进行强制类型转换,在C语言中却无必要。

《C专家编程》读书笔记之第8~11章的更多相关文章

  1. c专家编程读书笔记

    无论在什么时候,如果遇到malloc(strlen(str));,几乎可以直接断定他是错误的,而malloc(strlen(str)+1):才是正确的: 一个L的NUL哟关于结束一个ACSII字符串: ...

  2. 类型解释器——C专家编程读书笔记

    对于声明,应该按下面的步骤来进行解释: 1) 声明从它的名字开始读取,然后按照优先级顺序依次读取 2) 优先级顺序 a) 括号括起来的部分 b) 后缀操作符,()表示函数,[]表示数组 c) 前缀操作 ...

  3. Node.js高级编程读书笔记Outline

    Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...

  4. 《android开发进阶从小工到专家》读书笔记--HTTP网络请求

    No1: 客户端与服务器的交互流程: 1)客户端执行网络请求,从URL中解析出服务器的主机名 2)将服务器的主机名转换成服务器的IP地址 3)将端口号从URL中解析出来 4)建立一条从客户端与Web服 ...

  5. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

  6. C++Windows核心编程读书笔记

    转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...

  7. CSAPP 并发编程读书笔记

    CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...

  8. DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  9. unix环境高级编程-读书笔记与习题解答-第一篇

    从这周开始逐渐的进入学习状态,每天晚上都会坚持写c程序,并且伴随对这本书的深入,希望能写出更高质量的读书笔记和程序. 本书的第一章,介绍了一些关于unix的基础知识,在这里我不想去讨论linux到底是 ...

随机推荐

  1. linux 批量创建用户

    user 模块添加用户 python -c 'from passlib.hash import sha512_crypt; import getpass; print (sha512_crypt.en ...

  2. P2272 [ZJOI2007]最大半连通子图 tarjan+DP

    思路:$tarjan+DP$ 提交:1次 题解:首先对于一个强连通分量一定是一个半连通分量,并且形成的半连通分量的大小一定是它的$size$,所以我们先缩点. 这样,我们相当于要在新的$DAG$上找一 ...

  3. keydown([[data],fn]) 当键盘或按钮被按下时,发生 keydown 事件。

    keydown([[data],fn]) 概述 当键盘或按钮被按下时,发生 keydown 事件. 注释:如果在文档元素上进行设置,则无论元素是否获得焦点,该事件都会发生.直线电机滑台 参数 fnFu ...

  4. Chrome浏览器设置自动启用Flash插件

    Chrome浏览器设置自动启用Flash插件   1.打开Chrome浏览器,输入chrome://flags/#run-all-flash-in-allow-mode,打开,找到Enable Eph ...

  5. MongoDB 运维实总结

    一.MongoDB 集群简介 MongoDB是一个基于分布式文件存储的数据库,其目的在于为WEB应用提供可扩展的高性能数据存储解决方案.下面将以3台机器介绍最常见的集群方案.具体介绍,可以查看官网 h ...

  6. 把Cstring类型的字符串转化为char* 字符串;

    int char_leng; Cstring str="abcd"; char_leng=str.GetLength();//获取字符串长度 char *str_temp=(cha ...

  7. 在Android中使用OpenGL ES进行开发第(三)节:绘制图形

    一.前期基础知识储备笔者计划写三篇文章来详细分析OpenGL ES基础的同时也是入门关键的三个点: ①OpenGL ES是什么?与OpenGL的关系是什么?——概念部分 ②使用OpenGLES绘制2D ...

  8. Linux配置Tomcat8080端口 远程无法访问解决办法

    是因为Linux的防火墙没有开放8080端口 解决办法: /sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT #开启8080端口  /sbin/ ...

  9. PHP 之文件上传类封装

    一.前端代码 <!doctype html> <html lang="en"> <head> <meta charset="UT ...

  10. SQL连接查询基础知识点

    什么是连接 连接(join)查询是基于多个表中的关联字段将数据行拼接到一起,可以同时返回多个表中的数据. 下面以两个表为例子,举例说明一下不同的连接. SELECT * FROM products i ...