C和指针随笔

1.gets函数丢弃换行符,并在该行的末尾存储一个NUL字节。

2.NUL是ASCII字符集中’\0’字符的名字,它的字节模式为全0。NULL指一个其值为0的指针。

3.数组参数是以引用的形式进行传递的,即是传址调用,而标量和常量则是按值传递的。当数组名作为实参,传给函数的实际上是一个指向数组起始位置的指针,也就是在内存中的地址,正是实际传递的是一个指针而不是一份数组的拷贝,才使得数组名作为参数时具备了传址调用的含义。

4.函数void fuction(int array[], int len){};未指定数组长度的形参,这是一个伟大的特性,不论调用函数传递给它的数组参数长度是多少,它都能接收,允许单个函数操纵任意长度的一位数组。但是函数无法知道数组的长度,若需要知道数组的长度,则长度值必须作为一个单独的参数传递给函数。

int ch;
while ( (ch = getchar()) != EOF && ch != '\n' )

当使用scanf读取输入值时,只读取需要的字符,这样该输入行包含了最后一个值的剩余部分扔会留在那里,等待被读取,它可能是作为终止符的换行符,也可能包含其他字符。不论如何,while循环将读取并丢弃这些剩余的字符,防止它们被解释为下一行数据。
getchar函数从标准输入读取一个字符并返回它的值,如果输入中不再存在任何字符,函数就会返回常量EOF,用于提示文件的结尾。ch和EOF进行比较,若ch=EOF,整个表达式为假,循环终止。该表达式指当输入尚未到达文件尾并且输入的字符并非换行符时,循环才继续执行,这样这个循环就能剔除当前输入行最后的剩余字符。
值得注意的点是ch被声明为整型。EOF是个整型值,它的位数比字符长,把ch声明为整型可以防止从输入读取的字符意外地被解释为EOF,意味着接收字符的ch要够长去容纳EOF,因此被声明为int。

6.在程序中使用字符串常量会生成一个“指向字符的常量指针”,当一个字符串常量出现在一个表达式中时,表达式所使用的值就是这些字符所存储的地址,而不是这些字符本身。因此,可以把字符串常量赋值给一个“指向字符的指针”,后者指向这些字符所存储的地址。但是不能把字符常量赋值给一个字符数组,因为字符串常量的直接值是一个指针,而不是这些字符本身。

7.typedef

typedef char *ptr_to_char;
ptr_to_char a;	//声明a是一个指向字符的指针
//注意:应该使用typedef而不是#define来创建新的类型名,因为#define无法正确处理指针类型。如:
#define d_ptr_to_char char*
d_ptr_to_char a, b;	//相当于:char *a, b;正确的声明了a为指向字符的指针,但是b被声明为字符。

8.const

int *pi;	//pi是一个普通的指向整型的指针。
int const *pci;	//pci是一个指向整型常量的指针(指针常量)。可以修改指针的值,但不能修改它所指向的值。
int *const cpi;	//cpi是一个指向整型的常量指针(常量指针)。指针是常量,它的值无法修改,但可以修改它所指向的整型的值。
int const *const cpci;	//指针本身和它所指向的值都是常量,不能修改。

注意:const和#define声明常量:const变量只能用于允许使用变量的地方,而#define声明的变量,只要允许使用字面值常量的地方都可以使用,比如声明数组的长度,而const声明的常量不能用于数组的长度。

9.作用域:文件作用域、函数作用域、代码块作用域和原型作用域,标识符声明的位置决定它的作用域。
(1)代码块作用域:任何在代码块的开始位置声明的标识符都具有代码块作用域,表示它们可以被这个代码块中的所有语句访问。
注意:当代码块处于嵌套状态时,内层代码块的标识符的作用域到达该代码块的尾部结束。内层代码块的变量会隐藏外层相同名字的变量。每个代码块的变量无法被另一个代码块访问,因此编译器可以把它们存储于同一个地址。
(2)文件作用域:任何在所有代码块之外声明的标识符都具有文件作用域,表示这些标识符从它们的声明之处开始知道它所在的源文件结尾处都是可以访问的。
(3)原型作用域:只适用于在函数原型中声明的参数名。
(4)函数作用域:只适用于语句标签,语句标签用于goto语句。

10.链接属性——external(外部)、internal(内部)、none(无)
当组成一个程序的各个源文件分别被编译之后,所有的目标文件以及那些从一个或多个函数库中引用的函数链接在一起,形成可执行程序。
none:没有链接属性的标识符总是被当做单独的个体,即是说该标识符的多个声明被当作独立不同的实体。
internal:属于internal链接属性的标识符在同一个文件中的所有声明都指同一个实体,但位于不同源文件的多个声明则分属不同的实体。
external:属于external链接属性的标识符不论声明多少次、位于几个源文件都表示同一个实体。
注意:关键字extern和static用于在声明中修改标识符的链接属性。如果某个声明在正常情况下具有external链接属性,在前面加上static就可以使其链接属性变为internal。

11.存储类型:存储类型有auto, extern, register, static;存储空间:数据区、BBS区、栈区、堆区
(1)auto存储类型:auto只能用来标识局部变量的存储类型,对于局部变量,auto是默认的存储类型,不需要显示的指定。因此,auto标识的变量存储在栈区中。
(2)extern存储类型:extern用来声明在当前文件中引用在当前项目中的其它文件中定义的全局变量。如果全局变量未被初始化,那么将被存在BSS区中,且在编译时,自动将其值赋值为0,如果已经被初始化,那么就被存在数据区中。全局变量,不管是否被初始化,其生命周期都是整个程序运行过程中,为了节省内存空间,在当前文件中使用extern来声明其它文件中定义的全局变量时,就不会再为其分配S内存空间。
(3)register存储类型:声明为register的变量在由内存调入到CPU寄存器后,则常驻在CPU的寄存器中,因此访问register变量将在很大程度上提高效率,因为省去了变量由内存调入到寄存器过程中的好几个指令周期。
(4)static存储类型:被声明为静态类型的变量,无论是全局的还是局部的,都存储在数据区中,其生命周期为整个程序,如果是静态局部变量,其作用域为一对{}内,如果是静态全局变量,其作用域为当前文件。静态变量如果没有被初始化,则自动初始化为0。静态变量只能够初始化一次
(5)字符串常量:字符串常量存储在数据区中,其生存期为整个程序运行时间,但作用域为当前文件。
总结如表:
存储类型表

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值