《C语言深度剖析》笔记

来源:互联网 发布:分区容错性 知乎 编辑:程序博客网 时间:2024/05/16 03:26
《C语言深度剖析》笔记

1.在c语言中,凡不加返回值类型限定的函数,就会被编译器作为返
回整形处理。 
2.register 变量必须是一个单个的值,并且其长度应小于或等于整型
的长度。而且 register 变量可能不存放在内存中, 所以不能用取
址运算符 “&”来获取 register变量的地址。 
3. int main() 

char a[1000]; 
int i; 
for(i=0; i<1000; i++) 

a[i] = -1-i; 

printf("%d",strlen(a)); 
return 0; } 
此题看上去真的很简单,但是却鲜有人答对。答案是 255。别惊讶,
我们先分析分析。for循环内,当 i 的值为 0时,a[0]的值为-1。
关键就是-1在内存里面如何存储。我们知道在计算机系统中,数值

一律用补码来表示(存储) 。主要原因是使用补码,可以将符号
位和其它位统一处理;同时,减法也可按加法来处理。另外,两个
用补码表示的数相加时,如果最高位(符号位)有进位,则进位被
舍弃。正数的补码与其原码一致;负数的补码:符号位为 1,其余
位为该数绝对值的原码按位取反,然后整个数加 1。按照负数补码
的规则,可以知道-1 的补码为0xff,-2 的补码为0xfe……当 i 的
值为127时,a[127]的值为-128,而-128是char类型数据能表示的
最小的负数。当 i 继续增加,a[128]的值肯定不能是-129。因为这
时候发生了溢出,-129 需要 9 位才能存储下来,而 char类型数
据只有 8 位,所以最高位被丢弃。剩下的 8 位是原来 9 位补码
的低 8 位的值,即 0x7f。当 i 继续增加到255的时候,-256的
补码的低 8位为 0。然后当i增加到 256时,-257的补码的低 8 位
全为1,即低八位的补码为 0xff,如此又开始一轮新的循环……按
照上面的分析,a[0]到 a[254]里面的值都不为 0,而 a[255]的值为 
0。strlen函数是计算字符串长度的,并不包含字符串最后的‘\0’ 。
而判断一个字符串是否结束的标志就是看是否遇到‘\0’ 。如果
遇到‘\0’ ,则认为本字符串结束。分析到这里,strlen(a)的值为 
255应该完全能理解了。这个问题的关键就是要明白 char类型默
认情况下是有符号的,其表示的值的范围为[-128,127],超出这个
范围的值会产生溢出。 另外还要清楚的就是负数的补码怎么表示。 
弄明白了这两点, 这个问题其实就很简单了。 
4.case 后面只能是整型或字符型的常量或常量表达式(想想字符型


数据在内存里是怎么存的) 。 
5. 不能对 void指针进行算法操作。 
6. return 语句不可返回指向“栈内存”的“指针” ,因为该内存在
函数体结束时被自动销毁。 
7. struct student 
{}stu; sizeof(stu)的值是多少呢?是1。即空结构体的大小就定位 1 
个byte。 
8. 编译器会将注释剔除,但不是简单的剔除,而是用空格代替原来
的注释。 
9. 注意:/*…*/这种形式的注释不能嵌套,因为/*总是与离它最近的
*/匹配。 
10.const修饰的只读变量不能用来作为定义数组的维数, 
也不能放在 case关键字后面。 
11. C语言里(\)表示断行。以反斜杠反斜杠之后不能有空格,反斜
杠的下一行之前也不能有空格。 
12. 注释先于预处理指令被处理。因此,试图用宏开始或结束一段 
注释是不行的。 
13.在32位系统下,不管什么样的指针类型,其大小都为 4byte。 
14. 往内存 0x12ff7c地址上存入一个整型数 0x100,可以用下面的方
法:int *p = (int *)0x12ff7c; 
*p = 0x100; 
或者直接这么写代码:*(int *)0x12ff7c = 0x100; 


15. int a[5];a作为右值时,代表数组首元素的首地址,而非数组的首
地址。 
16.以指针的形式访问数组; 
如:#include<stdio.h> 
void main() 
{int a[5],i=0; 
for(i=0;i<5;i++) 
{a[i]=i; 
printf("%d\n",*(a+i)); 



17. 以下标的形式访问指针; 
如:#include<stdio.h> 
void main() 
{int a[5],i=0,*p; 
p=a; 
for(i=0;i<5;i++) 
{a[i]=i; 
printf("%d, ",p[i]); 




18. 对指针进行加1操作,得到的是下一个元素的地址,一个类型为
T的指针的移动,以 sizeof(T) 为移动单位。 
例:#include<stdio.h> 
void main() 
{int a[5]={1,2,3,4,5}; 
int *ptr=(int *)(&a+1); 
printf("%d,%d",*(a+1),*(ptr-1)); 


19. 函数本身是没有类型的,只有函数的返回值才有类型。 
20. malloc函数的原型:(void *)malloc(int size)。malloc函数的返回值
是一个 void类型的指针,参数为 int 类型数据。内存分配成功之
后,malloc函数返回这块内存的首地址。你需要一个指针来接收这
个地址。malloc函数申请的是连续的一块内存。注意malloc函数
申请内存有可能不成功,所以我们在使用指向这块内存的指针时,
必须用 if(NULL !=p)语句来验证内存确实分配成功了。 
注意:用 malloc函数申请 0字节时,内存不会返回 NULL指针,
而是返回一个正常的内存地址。但是你却无法使用这块大小为 0 
的内存。对于这一点一定要小心,因为这时候 if(NULL !=p)语
句校验将不起作用。 
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电脑开机变慢了怎么办 怎么办抚顺韦德健身卡 预售健身卡合法吗怎么办 被浓硫酸泼到怎么办 婴儿误喝了生水怎么办 宝宝喝了生水拉肚子怎么办 因妈妈喝生水宝宝拉肚子怎么办 喝了几口生水怎么办 不小心吃到蟑螂怎么办 吃了有蛆的樱桃怎么办 不小心误食了蛆怎么办 吃了有蟑螂的汤怎么办 调节天平时指针向右怎么办 香薰蜡烛融化了怎么办 香薰蜡烛挂壁怎么办y 粗蜡烛只烧中间怎么办 紫薯馒头变绿怎么办 小孩手开水烫了怎么办 被油烫伤了怎么办才不留疤 烫伤水泡蹭破了怎么办 烧伤的水泡破了怎么办 烧伤后水泡破了怎么办 烫伤泡破了红肿怎么办 烧伤第二天水泡破了怎么办? 烧伤后换药特别疼怎么办 盐酸溅到皮肤上怎么办 磷性磷酸酶高440怎么办 浓硫酸沾到皮肤上怎么办 浓硫酸溅到皮肤上怎么办 浓硫酸滴到皮肤上怎么办 浓硫酸洒在皮肤上怎么办 浓硫酸溅到眼睛里怎么办 盐酸弄到眼睛了怎么办 稀硫酸进眼睛里怎么办 草酸弄到皮肤上怎么办 大理石被盐酸烧发白怎么办 香薰蜡烛化了怎么办 吸入了大量燃烧纸气体怎么办 狗链条上锈了怎么办 思维迟钝反应慢嘴笨怎么办 小孩思维慢反应迟钝怎么办