《C专家编程》读书笔记之第8~11章
八、为什么程序员无法分清万圣节和圣诞节
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章的更多相关文章
- c专家编程读书笔记
无论在什么时候,如果遇到malloc(strlen(str));,几乎可以直接断定他是错误的,而malloc(strlen(str)+1):才是正确的: 一个L的NUL哟关于结束一个ACSII字符串: ...
- 类型解释器——C专家编程读书笔记
对于声明,应该按下面的步骤来进行解释: 1) 声明从它的名字开始读取,然后按照优先级顺序依次读取 2) 优先级顺序 a) 括号括起来的部分 b) 后缀操作符,()表示函数,[]表示数组 c) 前缀操作 ...
- Node.js高级编程读书笔记Outline
Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...
- 《android开发进阶从小工到专家》读书笔记--HTTP网络请求
No1: 客户端与服务器的交互流程: 1)客户端执行网络请求,从URL中解析出服务器的主机名 2)将服务器的主机名转换成服务器的IP地址 3)将端口号从URL中解析出来 4)建立一条从客户端与Web服 ...
- python高级编程读书笔记(一)
python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- CSAPP 并发编程读书笔记
CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...
- DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- unix环境高级编程-读书笔记与习题解答-第一篇
从这周开始逐渐的进入学习状态,每天晚上都会坚持写c程序,并且伴随对这本书的深入,希望能写出更高质量的读书笔记和程序. 本书的第一章,介绍了一些关于unix的基础知识,在这里我不想去讨论linux到底是 ...
随机推荐
- java中vector中add,addElement区别
这两个方法最大的区别就是返回值不一样,在作用上基本没有区别. add是实现List接口重写的方法,返回值为boolean.addElement是Vector类中的特有方法,返回值是void.
- AbstractWrapper ,EntityWrapper, QueryWrapper, UpdateWrappe
https://blog.csdn.net/qq_42112846/article/details/88086035 https://blog.csdn.net/m0_37034294/article ...
- CF940F Machine Learning 带修改莫队
题意:支持两种操作:$1.$ 查询 $[l,r]$ 每个数字出现次数的 $mex$,$2.$ 单点修改某一位置的值. 这里复习一下带修改莫队. 普通的莫队中,以左端点所在块编号为第一关键字,右端点大小 ...
- bzoj 5072
对于某一大小的连通子图包含的黑点的数目的最大值和最小值都能取到考虑树形dp$f[i][j]$ 表示从 $i$ 的子树中选出大小为 $j$ 的联通子图黑点数目的最小值$g[i][j]$ 表示从 $i$ ...
- Scarily interesting! (URAL - 2021)
Problem This year at Monsters University it is decided to arrange Scare Games. At the Games all camp ...
- RabbitMQ 和 Kafka 的消息可靠性对比
RabbitMQ和Kafka都提供持久的消息保证.两者都提供至少一次和至多一次的保证,另外,Kafka在某些限定情况下可以提供精确的一次(exactly-once)保证. 让我们首先理解一下上述术语的 ...
- 在树莓派4b上安装 ROS MELODIC 源码安装
按照以下步骤照做就可以了,很简单的,就是浪费一点点时间罢了.也可以退而求其次,买个树莓派3B+来玩,哈哈. Step 1: Install Dependecies and Download the P ...
- Jenkins系统初始化配置
1.点击系统管理-->全局安全配置 2.设置允许用户注册,点击保存 3.配置全局工具 4.配置maven文件路径,使用文件系统中的settings文件 5.配置jdk 6.配置maven 7.我 ...
- 【Golang】嗅探抓包,解决线上偶现问题来不及抓包的情况
背景 测试群里经常看到客户端的同学反馈发现了偶现Bug,但是来不及抓包,最后不了了之,最近出现得比较频繁,所以写个小脚本解决这个问题. 实现思路 实现的思路比较简单: 抓包 存日志 做日志管理 具体实 ...
- memcached出现:Fatal error: Call to undefined method Memcached::connect()
今天安装了memcached的服务端和客户端 装好试了一下 $mem = new Memcached; $mem -> connect("127.0.0.1",11211) ...