C语言深度剖析总结(一)
2010年07月23日
1.register关键字请求编译器尽可能的将变量存储在CPU内部寄存器中而不是内存中以提高访问效率。
数据从内存中取出来首先放到寄存器中,然后CPU再从寄存器中读取数据来进行处理,处理完后同样通过寄存器放到内存中, CPU不直接和内存打交道。
Register的值必须是一个单个的值,并且其长度应小于或等于int的长度,而且register变量可能不放在内存中,所以不能用取地址符(&)来获取register变量的地址。
2. #include #include using namespace std; int main(int argc, char *argv[]) { char a[1000]; for(int i=0; i #include #include using namespace std; int main() { //freopen("output.txt", "wt", stdout); int i = -20; unsigned j = 10; bitset b(i + j); int res = i + j; cout #include using namespace std; int main() { unsigned i; for(i=9; i>=0; i--) cout =0, 所以上面的for()是个死循环…
5.如果函数没有返回值,那么声明为void 类型。在C语言中,如果不加返回值类型限定,那么编译器将函数返回值默认为int类型,不是void。
如果函数无参数,那么声明其参数为void
6. 如果函数的参数可以是任意类型的指针,那么声明其参数为void*类型,想标准库中的memcpy(), memset()函数,他们的指针参数的类型和返回值类型都是void*类型的,这也真实体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这篇内存的类型是什么。
7. void不能代表一个真实的变量,因为定义变量时必须分配内存空间,定义void类型变量,编译器到底应该为变量分配多大的空间呢?所以不行…
void a; // error
fun(void a);// error
8. 编译器通常不为普通的const只读变量分配存储空间,而是将他们保存在符号表中,这使得他成为一个编译期间的值,没有了读写内存的操作,使得他的效率也很高。
例如:
#define M 3
const int N = 5; //此时并未将N放入内存中,只是保存在符号表中
…
int i = N; //此时为N分配内存,以后不再分配
int j = N; //此时不为N分配内存
int k = M; //预编译期间进行宏替换,分配内存
int l = M; //再次进行宏替换,分配内存
const定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是向#define一样给出的是立即数,所以, const定义的只读变量在程序运行过程中只有一份拷贝(因为他是全局的只读变量,放在静态存储区),而#define定义的宏常量在内存中有若干份拷贝。
#define宏是在预编译阶段进行替换,而const修饰的只读变量是在编译的时候确定其值。
#define宏没有类型,而const修饰的只读变量具有特定的类型,所以在编译的时候还能够进行类型检查。
9. volatile 关键字和const 一样是一种类型修饰符,用它修饰的变量表示可以被某些编译器
未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编
译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
先看看下面的例子:
int i=10;
int j = i;//(1)语句
int k = i;//(2)语句
这时候编译器对代码进行优化,因为在(1)、(2)两条语句中,i 没有被用作左值。这时候编译器认为i 的值没有发生改变,所以在(1)语句时从内存中取出i 的值赋给j 之后,这个值并没有被丢掉,而是在(2)语句时继续用这个值给k 赋值。编译器不会生成出汇编代码重新从内存里取i 的值,这样提高了效率。但要注意:(1)、(2)语句之间i 没有被用作左值才行。
再看另一个例子:
volatile int i=10;
int j = i;//(3)语句
int k = i;//(4)语句
volatile 关键字告诉编译器i 是随时可能发生变化的,每次使用它的时候必须从内存中取出i
的值,因而编译器生成的汇编代码会重新从i 的地址处读取数据放在k 中。
这样看来,如果i 是一个寄存器变量或者表示一个端口数据或者是多个线程的共享数
据,就容易出错,所以说volatile 可以保证对特殊地址的稳定访问。
10.const volatile int i = 10;
这个表示i是一个const常量, 不能够被用户代码改变, 但是i可以被其他因素改变。
下面是找到的一些分析:
const表示我们自己的代码不会改变这个值(别的代码或者硬件有可能改变这个值)。volatile表示禁止优化。因为编译器会认为如果代码没有改变变量,那么这个变量就不会改变,因此编译器会用寄存器把该变量缓存起来,每次需要读取变量值的时候,就从缓存中读取。这在大多数时候是正确的,但是在多线程或者中断的场合就不正确了。
一个值可以同时是const和volatile。例如,硬件时钟一般设定为不能由程序改变,这一点使他成为const; 但它被程序以外的代理改变,这使它成为volatile的。只需在声明中同时使用这两个限定词。
volatile标识一个变量意味着这个变量可能被非本程序的其他过程改变,例如某个访问这一变量的某中断程序。
CSDN讨论链接:
http://topic.csdn.net/u/20071210/14/321d6ec5-f967- 4afb-8d04-b335e6db7b34.html
11.柔性数组:
C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员,但结
构中的柔性数组成员前面必须至少一个其他成员。柔性数组成员允许结构中包含一个大小可
变的数组。sizeof 返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用
malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组
的预期大小。
柔性数组到底如何使用呢?看下面例子: typedef struct st_type { int i; int a[0]; }type_a; 有些编译器会报错无法编译可以改成:
typedef struct st_type
{
int i;
int a[];
}type_a;
这样我们就可以定义一个可变长的结构体,用sizeof(type_a) 得到的只有4 , 就是
sizeof(i)=sizeof(int)。那个0 个元素的数组没有占用空间,而后我们可以进行变长操作了。通
过如下表达式给结构体分配内存:
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
这样我们为结构体指针p 分配了一块内存。用p->item[n]就能简单地访问可变长元素。
但是这时候我们再用sizeof(*p)测试结构体的大小,发现仍然为4。是不是很诡异?我们
不是给这个数组分配了空间么?
别急,先回忆一下我们前面讲过的"模子"。在定义这个结构体的时候,模子的大小就
已经确定不包含柔性数组的内存大小。柔性数组只是编外人员,不占结构体的编制。只是说
在使用柔性数组时需要把它当作结构体的一个成员,仅此而已。再说白点,柔性数组其实与
结构体没什么关系,只是"挂羊头卖狗肉"而已,算不得结构体的正式成员。
12.Big Endian和Little Endian:
Big Endian(大端模式):字数据的高字节存储在低地址中, 而字数据的低地址则存放在高地址中。
Little Endian(小端模式):字数据的高字节存储在高地址中, 而字数据的低地址存放在低地址中。
判断系统存储模式: #include using namespace std; int check() { union { int i; char ch; }c; c.i = 1; return c.ch; } int main() { int res = check(); if(res == 0) cout using namespace std; #define swap(a) a = ((unsigned int)a >> 24) | ((unsigned int)a >> & 0x0000ff00 | (a #include using namespace std; enum enum_name { ONE, TWO, THREE = 5 }enum_obj; int main(int argc, char *argv[]) { cout #include using namespace std; typedef struct _TEST { int a; _TEST& operator =(int i) { a = i; return *this; } }TEST, *PTRTEST; int main(int argc, char *argv[]) { TEST test1; TEST test2; const PTRTEST ptr1 = &test1; PTRTEST const ptr2 = &test1; //ptr1 = &test2; //error: ptr1 read only //ptr2 = &test2; //error: ptr1 read only *(ptr1) = 1; *(ptr2) = 2; system("PAUSE"); return EXIT_SUCCESS; } 这段代码中,定义了两个TEST类型的指针,const PTRTEST ptr1,PTRTEST const ptr2,这两种形式都是定义了一个指针常量,就如同const int I和int const I都是定义个一个常量I一样。对于编译器来说,只认为PTRTEST 是一个类型,并不去管他不是不指针类型。
源自:《C 语言深度解剖》(陈正冲编著)
发表评论
-
uboot讲解
2012-01-20 08:21 699uboot讲解 2010年09月15日 实验:p167 ... -
Proc 文件系统信息
2012-01-20 08:21 599Proc 文件系统信息 2011年03月30日 Proc ... -
第二章 Android内核和驱动程序(转)
2012-01-20 08:21 751第二章 Android内核和驱 ... -
java线程安全总结
2012-01-20 08:19 427java线程安全总结 2010年11月11日 转载自:h ... -
zz:OpenGL实用开源代码列表
2012-01-19 13:34 688zz:OpenGL实用开源代码列 ... -
2011-7-27
2012-01-19 13:34 6192011-7-27 2011年07月27日 CS1.6完 ... -
【装机至尊】《中关村GHOSTXPSP3纯净装机自选DVD特别版V201011A》(海量驱动)
2012-01-19 13:34 556【装机至尊】《中关村G ... -
工作站电脑配件详解(仅以45纳米双路四核至强及NV Quadro FX图形卡为例,还有价格):
2012-01-19 13:34 816工作站电脑配件详解(仅以45纳米双路四核至强及NV Quadr ... -
苹果4代电池不耐用iphone论坛!入手IPHONE必看!
2012-01-17 03:23 808苹果4代电池不耐用iphone ... -
笔记本电脑死机 笔记本老是死机 蓝屏死机
2012-01-17 03:23 549笔记本电脑死机 笔记本 ... -
9 种可重复使用的并行数据结构和算法
2012-01-17 03:23 4689 种可重复使用的并行数据结构和算法 2011年10月16日 ... -
as3面试题
2012-01-17 03:23 608as3面试题 2011年09月13日 ... -
2011-11-1
2012-01-17 03:23 4322011-11-1 2011年11月01日 第一篇:一 ... -
我与三抗情
2012-01-16 01:57 424我与三抗情 2009年08月08日 07 ... -
坏蛋是怎样炼成的5
2012-01-16 01:57 1006坏蛋是怎样炼成的5 2009 ... -
java读取文件输出流出现的问题
2012-01-11 01:57 588java读取文件输出流出现的问题 2011年08月01日 ... -
GT-Grid 1.0 基础教程(十)
2012-01-11 01:56 479GT-Grid 1.0 基础教程(十) 2011年08月01 ... -
autocomplete自动匹配
2012-01-11 01:56 574autocomplete自动匹配 2011年08月01日 ... -
Oracle Express 修改字符集,升级APEX
2012-01-11 01:56 638Oracle Express 修改字符集,升级APEX 20 ... -
java多线程及线程池小结-atomti-iteye技术网站
2012-01-11 01:56 509java多线程及线程池小结 ...
相关推荐
c语言深度剖析 c语言深度剖析 c语言深度剖析 c语言深度剖析
C语言深度剖析 -------------------解开程序员面试笔试的秘密
C非常不错的语言深度剖析,适合有一定基础的C语言爱好者阅读
讲述了c语言基础知识,对内存管理这片雷区做了深度的讲解,对函数的使用也进行了详细的阐述。
C语言深度剖析 C语言深度剖析 C语言深度剖析 C语言深度剖析 C语言深度剖析 C语言深度剖析 C语言深度剖析
C语言深度剖析视频教程,里面附视频连接,密码!
C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析C语言深度剖析
[C语言深度剖析.-.解开程序员面试笔试的秘密].陈正冲.石虎.文字版,很难找的资源,分享给大家
C语言深度剖析 经典国内书籍, 研究C语言必备
C语言深度剖析 pdf+源代码 你懂的 我遇到过很多程序员和计算机系毕业的学生,也给很多程序员和计算机系毕业的学生讲 解过《高级C 语言程序设计》。每期班开课前,我总会问学生:你感觉C 语言学得怎么样? 难吗?指针...
c语言深度剖析剖析剖析c语言深度剖析剖析剖析c语言深度剖析剖析剖析
c语言深度剖析,内容讲的很不错。可以看看
一本很好的C语言深度剖析书籍,通读之后自己整理的思维导图
[C语言深度剖析.-.解开程序员面试笔试的秘密].陈正冲.石虎.文字版.pdf[C语言深度剖析.-.解开程序员面试笔试的秘密].陈正冲.石虎.文字版.pdf
解开程序员面试笔试的秘密 C语言深度剖析.-.解开程序员面试笔试的秘密
C语言深度剖析 ,完美解析C语言的各种易错点,适合毕业生笔试面试前使用。
c语言深度剖析,很好的一本C语言知识巩固书籍
C语言深度解剖 -------------------解开程序员面试笔试的秘密 以含金量勇敢挑战国内外同类书籍