C语言学习笔记(一):数组初始化的一种形式及C-V限定词
数组:
#include<stdio.h>
int main()
{
int i,a[]={8,9,10,11,56,13,[0]=2,12,18,23,[1]=5,6};
for(i=0;i<sizeof(a)/sizeof(int);i++)
printf("a[%d]=%d\n",i,a[i]);
printf("length=%d\n",sizeof(a)/sizeof(int));
}
运行结果:
(1)如果在一个指定初始化项目后跟有不止一个值,例如:[0]=2,12,18,23,则这些数值将用来对后续的数组元素初始化。即:[0]=2,则[1]=12,[2]=18``````
(2)如果多次对一个元素进行初始化,则最后一次有效。
C/C++关键字volatile:
volatile对应的变量可能在你的程序本身不知道的情况下发生改变
比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量
你自己的程序,是无法判定何时这个变量会发生变化
还比如,他和一个外部设备的某个状态对应,当外部设备发生操作的时候,通过驱动程序和中断事件,系统改变了这个变量的数值,而你的程序并不知道。
对于volatile类型的变量,系统每次用到他的时候都是直接从对应的内存当中提取,而不会利用cache当中的原有数值,以适应它的未知何时会发生的变化,系统对这种变量的处理不会做优化——显然也是因为它的数值随时都可能变化的情况。
一般说来,volatile用在如下的几个地方:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
volatile的语法和const的是一样的,但是volatile的意思是“在编译器认识的范围外,这个数据可以改变”。环境正在改变数据(可能通过多任务、多线程或者中断处理),所以,volatile告诉编译器不要擅自做出有关该数据的任何假定,优化期间尤其如此。
如果编译器说:“我已经把数据读进寄存器,而且再没有与寄存器接触”。一般情况下,它不需要再读这些数据。但是,如果数据是volatile修饰的,编译器就不能做出这样的假定,因为这个数据可能被其他进程改变了,它必须重读这个数据而不是优化这个代码来消除通常情况下那些冗余的读操作代码。
volatile的语法与const是一样的,为指明可以选择两个中的任何一个,把他们连在一起统称为c-v限定词(c-v qualifier)。
K&RC中并没有C-V限定词的概念,它源于C++。在C90标准的制定过程中,C-V限定词逐渐被广泛接受,最终也成为C90的一部分。
C-V限定词是指const和volatile这两个修饰符。
const在c里面的用法和在c++里面仍然有不少区别:
1 C++能够把(已用常量赋值的)const变量看作编译期常数,c没有这种功能。
e.g:const int BUFFER = 1024;
char buf[buffer];
所以,如果c程序员想定义编译期常数,还得乖乖地依靠预处理指令:
#define BUFFER 1024;
char buf[buffer];
2 C++默认const变量的链接性质是内部的,而c则相反,默认是外部的。
e.g:const int a = 0;
int main(void){}
上面的变量a由于是在函数的外部定义并且没有static修饰,所以在c语言里面毫无疑问应该是外部链接的,即其他文件的代码能够访问到它。
但在c++中,变量a默认是内部链接的,除非你显式加上extern修饰词。否则,其他文件是看不到const变量a的。
3 c只能允许用常量初始化const外部变量,c++没有这种限制。
e.g: int f(void);
const int a = f();
无论c和c++这方面有什么差别,可以预期的是,很多编译器都会把const外部变量放到只读数据区,这样就能进一步确保const变量不被修改。
为何c++中const外部变量默认是内部链接呢?
因为c++设计思想的其中一点就是:错误应该尽可能在编译期被检测出来。