C语言三剑客-C和指针、C专家编程、C陷阱和缺陷

阅读这三本书,记录一下平时没注意的细节点,持续更新…

C和指针

数据

1.四种基本类型是 整型、浮点型、指针、聚合类型(数组和结构等)
2.整型字面值缺省情况下是能完整容纳这个值的最短类型
3.字面值后加L/l为long整型,U/u为unsigned,数值前面以0开头为8进制,0x开头为16进制
4.字符常量类型总为int,单引号包围,’M’
5.宽字符常量:多字节字符常量前面加一个L,L’X’,需要运行环境支持才能使用
6.浮点类型存储非整数或远超过计算机整数所能表达的范围(unsigned int 型最大:4294967295 即10的10次方量级)
7.浮点类型缺省情况下都是double型,所有的浮点类型至少能容纳10-37~1037之间的任何值
8.字符串常量以NUL字节终止符结尾 “”空字符串依然有NUL
9.不允许修改字符串常量,如果需要修改字符串,请将其存储于数组中
10.程序中使用字符串常量会生成一个“指向字符串的常量指针”,使用时是指针
11.C函数库包含一组操纵字符串的函数
12.除char以外其他整型类型缺省情况下都是符号数,char因编译器而异
13.浮点类型除了long double之外,其余几个说明符(short signed unsigned)都是不可用的
14.编译器不检查数组下标是否在合法范围内,如果下标值是根据用户输入的数据产生的,那么必须进行检测
15.注意指针类型声明写法 int *a,*b,c 这条语句表达a产生的结果类型是int,*操作符执行的是间接访问操作,由此推定a是一个指向int的指针
16.函数如果不显式地声明返回值的类型,它就默认返回整型
17.作用域分为四类:文件作用域、函数作用域(只适用于语句标签,用于goto,一个函数中语句标签唯一)、代码块作用域、原型作用域(只适用于在函数原型中声明的参数名)
18.链接属性有3种:external(外部):不论声明多少次,位于几个源文件都表示同一实体、internal(内部):同一源文件内的所有声明指向同一实体,不同源文件的多个声明则分属不同的实体、none(无):该标识符多个声明都是独立不同的实体
19.关键字extern指定链接属性external(仅在第一次声明时有效),static指定链接属性internal
20.存储类型:普通内存(全局变量、静态变量,程序运行之前创建,程序执行期间始终存在)、运行时堆栈(代码内部声明的变量缺省类型是自动的automatic,执行到时创建,执行流离开该代码块时自动销毁)、硬件寄存器(关键字register用于自动变量的声明,存储于硬件寄存器,通常效率更高,实际使用情况根据编译器的寄存器优化方案决定)
21.静态变量初始化中,可以把想要的值放到程序执行时变量会用到的位置,可执行程序载入内存时,会将值赋给那个变量(即内存中位置不变)
22.Staic的理解:用于函数定义或代码块之外的变量声明时,用于修改标识符的链接属性,但标识符的存储类型和作用域不受影响(本来就是普通内存,本文件),只能在声明它们的源文件中访问;用于代码块内部的变量声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响(static只对external的声明才有改变链接属性的效果)。

语句

23.嵌套循环中,内层循环的break(结束)或continue(本次)只对内层循环起作用,无法影响外层
24.goto 语句标签;不建议使用,技巧:可用于立即从深层嵌套的循环中退出,但通过把深层嵌套的循环整体封装成一个函数,在深层嵌套处return效果一样

操作符和表达式

25.操作符 右移位分为逻辑移位和算数移位,无符号值都为逻辑移位,有符号数取决于编译器
26.位操作 置1:value=value|1<<bit_number; 清0:value=value&~(1<<bit_number);
27.Sizeof是一个单目操作符,判断它的操作数的类型长度,以字节为单位
28.a++与++a都复制一份变量值的拷贝,是一个右值,无法对它赋值,如++a=10不对
29.a++为复制后再增加变量a的值,拷贝值为a的值;++a为增加变量值后再复制,拷贝值为(a+1)的值
30.&&与||的短路求值特性:&&若左值为0,则不计算右值;||若左值为1,则不计算右值
31.逗号操作符(了解即可,基本没用):将两个或多个表达式分隔开来,这些表达式自左向右逐个进行求值,整个逗号表达式的值就是最后那个表达式的值
32.左值与右值:左值,显式的标识了一个可以存储结果值的地点,是一个位置;右值,指定了一个值;所以使用右值的地方可以使用左值,使用左值的地方不能使用右值
33.地址每一个值代表存的一个字节,是以字节为单位进行地址编码的
34.以字为单位存储的机器,每个字一般有2个或4个字节组成,有些机器要求边界对齐,即整型值存储的起始位置只能是某些特定的字节,通常是2或4的倍数

指针

35.指针未初始化,使用时可能发生错误,若指针指向非法地址,则会引发段违例(segmentation violation)或内存错误(memory fault);对于必须存储于特定边界的机器而言,如果处于内存中存储地址错误的边界上,对这个地址访问会产生总线错误(bus error)
36.对NULL指针解引用是违法的,在对指针解引用操作之前,必须确保它并非NULL指针
37.为了测试一个指针变量是否为NULL,可以将它与零值进行比较
38.&a是一个右值,因为无法得知这个地址值本身存储的位置,左值必须标识机器内存的特定位置,相同的道理,指针加减、自加自减是一个右值,但加上间接访问后就是一个左值
39.指针运算只有作用于数组中其结果才是可以预测的,指针运算使指针指向了数组第一个元素前面的内存位置或数组最后一个元素后面的内存位置都是非法的
40.加减整数是以指针类型为单位,如int*型加1即为加4字节

函数

41.函数原型即函数声明,编译器会记录函数参数数量,每个参数类型以及返回值的类型,之后就可以检查它的所有调用
42.函数原型具有文件作用域,所以单独写到.h文件中,在调用该函数的c文件中include,函数原型要与函数定义匹配
43.当程序调用一个无法见到原型的函数时,编译器便认为该函数返回一个整型值
44.C的所有参数都是传值调用的,会复制一份被传递参数的拷贝;传数组名或者指针其实也是拷贝了一份数组名或指针,通过这个拷贝的指针去操作原来的数组,给人一种传址调用的感觉
45.抽象数据类型ADT也叫黑盒设计,即用static关键字,使模块的用户除了定义好的接口之外,用户不能以任何方式访问模块
46.可变参数:需要包含stdarg.h头文件,头文件中声明了一个类型va_list和三个宏–va_start、va_arg和va_end;函数声明了一个名叫var_arg,用于访问参数列表的未确定部分;用va_start来初始化,参数为va_list变量名(var_arg)和省略号前最后一个有名字的参数;宏va_arg有两个参数,va_list变量和参数列表中下一个参数的类型;访问完毕最后一个可变参数之后,我们需要调用va_end

数组

47.数组名的值是一个指针常量

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值