下载此文档

C语言深度解剖读书笔记.pdf


文档分类:IT计算机 | 页数:约8页 举报非法文档有奖
1/8
下载提示
  • 1.该资料是网友上传的,本站提供全文预览,预览什么样,下载就什么样。
  • 2.下载该文档所得收入归上传者、原创者。
  • 3.下载的文档,不会出现我们的网址水印。
1/8 下载此文档
文档列表 文档介绍
该【C语言深度解剖读书笔记 】是由【小屁孩】上传分享,文档一共【8】页,该文档可以免费在线阅读,需要了解更多关于【C语言深度解剖读书笔记 】的内容,可以使用淘豆网的站内搜索功能,选择自己适合的文档,以下文字是截取该文章内的部分文字,如需要获得完整电子版,请下载此文档到您的设备,方便您编辑和打印。:..C语言深度解剖读书笔记之——C语言基础测试题前几天天看到这本书,感觉不错,在看之前,先做了后面的****题,结果只得了60多分,一直以为自己的基础还是不错的,做完后对了答案后,感觉自己的自信心一下全没有了,不过遇到问题解决问题,我用了2天时间好好研读了这本书,感觉真不错。虽然感觉都是一些基础的知识,但是我读的还是津津有味,感觉收获蛮多的,感谢这本书的作者陈正冲。呵呵,说来我本科专业和这位大牛还是同一个专业呢,呵呵。不是只有计算机科班出身的才能学好编程,知真正的高手都是自学的。今天就把我当时做错的题目和认为比较好的题目一个个写出来。再次分析下如果我在哪家公司遇到类似这种题目我会感觉这家公司出题很有水平,重基础,真正理解C语言的人才能得高分。注重细节,知其然知其所以然。,为什么?[cpp]viewplaincopyprint?1.#include<iostream>;(intargc,_TCHAR*argv[])5.{[10],str1[10];;(i=0;i<10;i++)9.{[i]='a';11.}(string,str1);<<string<<endl;("pause");;16.}#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*ar{charstring[10],str1[10];:..运行的时候回出现下面情况::0xC0000005:Accessviolation做这个题目的时候,我也知道字符串strcpy是以'\0'为结束标识的。会产生数组越界,但是表达不清楚。答案:运行到strcpy的时候可能会产生内存异常。因为:str1没有结束符标识,str1数组后面继续存储的可能不是'\0',而是乱码。Cout函数,对于输出char*类型,顺序打印字符串中的字符直到遇到空字符('\0')或打印了由精度指定的字符数为止。?为什么?[cpp]viewplaincopyprint?1.#include<iostream>;(intargc,_TCHAR*argv[])5.{[1000];;(i=0;i<1000;i++)9.{[i]=-1-i;11.}<<strlen(a)<<endl;("pause");;15.}#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*ar{chara[1000];做题目的时候没有考虑到字符溢出,自然做错了分析::..我们知道计算机底层只认识0,1,所以任何数据到了底层都会通过计算转换成0,1,那么负数是怎样存储呢?由于“-”无法存入内存,我们把它做个标记,把基本数据类型的最高位腾出来,用来存符号,同时约定如下:如果最高位是1,表明这个数是负数,其值为除最高位以外的剩余位的值添上这个“-”号。一个32位的signedint类型整数,其值表示的范围为:-;8位的char,其值表示的范围为。一个32位的unsignedint类型整数,其值表示的范围为:,8位的unsignedchar,其值表示的范围为。需要说明的是,在默认情况下,编译器默认的数据位signed类型。for循环内,当i的值为0时,a[0]的值为-,数值一律用补码来表示。在用两个补码的数相加时,如果最高位(符号位)有进位,则进位被舍弃。正数的补码与其原码一致;负数的补码:符号位为1,其余位为该数绝对值的原码按位取反,然后整个数+1.-1的补码为0xff,-2的补码为0xfe......当i的值为127时,a[127]的值为-128,而-128是char类型数据能表示的最小的负数。当i继续增加,a[128]的值肯定不能使-129,因为这时候发生了溢出。-129需要9位(110000001)才能存储下来,而char只有8位,所以最高位被丢弃,剩下的8位是原来9位补码(11111111)的低8位的值,即0x7f。当i继续增加到255时,-256的补码低8位全为0,然后当i增加到256时,-257的补码的低8位全为1,即低8位的补码为0xff,如此又开始一轮新的循环......按照上面的分析,a[0]~a[254]里面的值都不为0,而a[255],并不包含字符串最后的'\0'。判断一个字符串是否结束的标志就是看是否遇到'\0';如果遇到'\0',则认为字符串结束。由此分析,strlen(a)?什么时候需要使用代码(2)代码(1):intj=10;intj=i;intk=i;代码(2):volatileinti=10;intj=i;intk=i;基础知识:Volatile关键字和const一样,是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素改变,比如操作系统、硬件或者其他线程。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。:..intj=10;intj=i;//(1)语句intk=i;//(2)语句此时编译器对代码进行优化,这是因为在(1)(2)两条语句中,i没有被用作左值(没有被赋值)。这时候编译器认为i的值没有发生改变,所以在(1)语句时从内存中取出i的值赋给j之后,这个值并没有丢弃掉,而是在(2)语句时继续用这个值给k赋值。编译器不会生成出汇编代码重新从内存里取i的值,这样提高了效率。但是要注意的是:(1)(2)语句之间确认i没有被用作左值才行。volatileinti=10;intj=i;//(3)语句intk=i;//(4)语句volatile关键字告诉编译器,i是随时可能发生变化的,每次使用它的时候必须从内存中取出i的值,因而编译器生成的汇编代码会重新从i的地址处读出数据放在k中。这样看来,如果i是一个寄存器变量,表示一个端口数据或者是多个线程的共享数据,那么就容易出错,所以volatile可以保证对特殊地址的稳定访问。,输出的值是多少?[cpp]viewplaincopyprint?1.#include<iostream>;(intargc,_TCHAR*argv[])5.{[5]={1,2,3,4,5};*ptr1=(int*)(&a+1);*ptr2=(int*)((int)a+1);<<hex<<ptr1[-1]<<endl<<hex<<*ptr2<<endl;("pause");;12.}#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*ar{inta[5]={1,2,3,4,5};:..运行结果:52000000分析:这里需要注意的是&a是整个数组的首地址,a是数组首元素的首地址,其值相同,但是意义不同。对于指针p+1,指针变量与一个整数相加减并不是用指针变量里的地址直接加减这个整数,这个整数的单位不是字节而是元素的个数。知道了这些就好办了。int*ptr1=(int*)(&a+1);&a+1这下加的1跑到了a[5](虽然不存在),ptr1[-1]=*(ptr1-1),这下跑到了a[4],所以结果是5;int*ptr2=(int*)((int)a+1);a是数组a的首元素的首地址。(int)a+1是元素a[0]的第二个字节的地址。由于是int型,所以占4个字节大端模式:a[0]a[1]a[2]a[3]12340x000x000x000x010x000x000x000x020x000x000x000x030x000x000x000x04在32位的x86系统下,是小端模式——认为第一个字节是最低位字节在内存中存放为:a[0]a[1]0x010000000x02000000所以读取为:0x02000000答案为:,如下表达式的值分别为多少?[cpp]viewplaincopyprint?1.#include<iostream>;(intargc,_TCHAR*argv[])5.{.{;*pcName;:..;[2];[4];13.}*p;=(Test*)0x100000;<<hex<<(p+0x1)<<endl;<<hex<<((unsignedlong)p+0x01)<<endl;<<hex<<((unsignedint*)p+0x01)<<endl;("pause");;20.}#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*ar{structTest运行结果为:这里还是记住一句话:指针p+1,指针变量与一个整数相加减并不是用指针变量里的地址直接加减这个整数,这个整数的单位不是字节而是元素的个数。p+0x1的值为0x100000+sizeof(Test)*0x01=0x100014(unsignedlong)p+0x01这里涉及到强制类型转换,将指针变量p保存的值强制转换成无符号的长整形数。任何数值一旦被强制转换,其类型就变了,所以这个表达式其实就是一个无符号的长整形数加上另一个整数,其值为0x100000+0x1=0x100001(unsignedint*)p+0x01,这里p被强制转换成一个指向无符号整形的指针,所以其值为:0x100000+sizeof(unsignedint)*0x01=?[cpp]viewplaincopyprint?1.#include<iostream>;:..(intargc,_TCHAR*argv[])5.{[3][2]={(0,1),(2,3),(4,5)};*p;=a[0];<<p[0];("pause");;12.}#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*ar{inta[3][2]={(0,1),(2,3),(4,运行结果:1这里需要注意的是{}里面是逗号表达式,inta[3][2]={(0,1),(2,3),(4,5)};相当于inta[3][2]={(1,3,5};?为什么?[cpp]viewplaincopyprint?1.#include<iostream>;.{*name;;8.}stu,*pstu;(intargc,_TCHAR*argv[])11.{=(structstudent*)malloc(sizeof(structstudent));->name=(char*)malloc(20);:..(pstu->name,"Jimy");->score=99;(pstu);("pause");;19.}#include<iostream>usingnamespacestd;structstudent{char*name;运行错误:()处未处理的异常:0xC0000005:写入位置0xcdcdcdcd时发生访问冲突为指针变量pstu分配了内存,但是没有给name指针分配内存。在为结构体指针分配内存的时候,是从外向里,即先分配结构体的指针,再分配成员指针,释放的时候,是从里向外,先释放成员指针,再释放结构体指针,顺序不能错。正确的修改应该是:pstu=(structstudent*)malloc(sizeof(structstudent));pstu->name=(char*)malloc(20);引自:

C语言深度解剖读书笔记 来自淘豆网www.taodocs.com转载请标明出处.

相关文档 更多>>
非法内容举报中心
文档信息
  • 页数8
  • 收藏数0 收藏
  • 顶次数0
  • 上传人小屁孩
  • 文件大小636 KB
  • 时间2024-04-14