auto即C语言中局部变量的默认属性,编译器默认所有的局部变量都是auto,它存储在程序的栈中
static修饰的局部变量存储在程序静态区。所以这个变量不在栈上,调用函数的时候这个变量不会因为函数运行结束,栈被释放而释放。它修饰的变量只会被初始化一次。
register指明将变量存储于寄存器中。由于寄存器是有限的,所以register只是请求寄存器变量,但不一定请求成功。必须满足以下条件:
1、 register变量的必须是CPU寄存器可以接受的值
2、 不能用&运算符获取register变量的地址。因为它存储于寄存器,所以不可能有内存里的地址。
从寄存器中取值会比从内存中取值要快的多,所以一般在实时性系统中运用寄存器变量。对频繁调用的函数和速度要求高的程序一般也使用寄存器变量。
void修饰函数返回值和参数仅为了表示无,所以不知道内存里void是多大的别名
void指针的意义:
1、 C语言只有相同类型的指针才可以相互赋值
2、 void*指针作为左值用于“接收”任意类型的指针
3、 void*指针作为右值赋值给其他指针时需要强制类型转换
sizeof不是函数,是个关键字
const修饰指针——左数右指:当const出现在*号左边时指针指向的数据为常量,当const出现在*号右边时指针本身为常量
const int*p; // p可变,p指向的内容为常量
int const*p; // p可变,p指向的内容为常量
int* const p; //p为常量,p指向的内容可变
const int*const p; //p和p指向的内容都为常量
const修饰函数参数表示在函数体内不允许被改变,修饰函数返回值表示返回值不可改变,多用于返回指针的情形
volatile:用于告诉编译器必须每次去内存中取变量值,主要修饰可能被多个线程访问的变量,也可以修饰可能被未知因素更改的变量,下面举例说明:
int obj = 10;
int a = 0;
int b = 0;
a = obj;
sleep(100);
b = obj;
这种情况下,a和b都会被赋值为10,假如在sleep(100);内产生了一个硬件中断,中断处理程序改变了obj里的值,但是b还是10。这样就可能出错。
这时只要这样写volatile int obj= 10;就可以每次都去内存中取值了。
struct中的每个域在内存中都独立分配空间
union只分配最大域的空间,所有域共享这个空间,它的使用受系统大小端的影响(低位在高字节为大端模式,小端你懂得)
typedef用于给一个已经存在的数据类型重命名,不是重定义的操作,没有产生新的类型,typedef重定义的类型不能进行unsigned和signed扩展
你知道下面哪些注释是正确的吗?
A) int/*…*/i;
B) char* s=”abcdefgh //hijklmn”;
C) //Is it a \
valid comment?
D) In/*…*/ti;
答案:前三个是正确的,编译器对注释用一个空格代替。注释符合在双引号之间就是一个普通的符合。
编译器将/*作为一段注释的开始,把/*后的内容都当成注释内容,直到*/出现为止。
接续符(\)表示这行还没结束,后面的内容也是这一行的。
编译器会将\剔除,跟在反斜杠后面的字符自动接到前一行;在接续单词时,反斜杠之后不能有空格,反斜杠的下一行之前不能有空格;接续符适合在定义宏代码块时使用
宏代码块的定义:
#define SWAP(a,b)\
{ \
inttemp=a; \
a=b; \
b=temp; \
}
可以定义一个这样的宏,方便代码的阅读。
逻辑运算符使用分析
||从左向右开始计算,当遇到为真的条件时停止计算,整个表达式为真;所有条件为假时表达式才为假。
&&从左向右开始计算,当遇到为假的条件时停止计算、整个表达式为假;所有条件为真时表达式才为真。
三目运算符(a?b:c)当a的值为真时,返回b的值;否则返回c的值
本文深入探讨C语言的各种特性,包括auto、static与register的作用及区别,void指针的应用,sizeof关键字的特点,const修饰符的不同用法,volatile的作用,以及struct与union的内存分配方式等。
924

被折叠的 条评论
为什么被折叠?



