1、sizeof 运算符:sizeof的结果等于对象或者类型所占的内存字节数;sizeof的影响因素:#pragma pack( n ),n为字节对齐数
A、参数为数据类型或者为一般变量。如int类型在16位系统中占2个字节,在32位系统中占4个字节。
B、参数为数组或指针
int a[50]; //sizeof(a)=4*50=200; 求数组所占的空间大小
int *a=new int[50];// sizeof(a)=4; a为一个指针,sizeof(a)是求指针
sizeof(*a) =4;
C、参数为结构或类
结构或者类中的静态成员不对结构或者类的大小产生影响,静态变量的存储位置和类或者结构体无关
class Test{int a; static double c;};//sizeof(Test)=4;
没有成员变量的结构或类的大小为1,目的是保证类或者结构体在内存中的地址唯一
class test1{};//sizeof(test1)=1;
2、extern
A、在本文件中,若想先使用未定义变量则可用extern,这种用法意义不大;
B、在同一个工程中,一个文件想引用另一个文件中已定义的外部变量是,则需在引用变量文件中用extern关键字加以声明即可
C、extern “C”:比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接
3、volatile
A、作用:作为指令关键字,确保本条指令不会因为编译器的优化而省略,且要求直接读值,简单的说就是防止编译器对代码进行优化,直接存取原始内存地址。
优化器再用到volatile修饰的变量的时候必须每次都小心地重读去这个变量的值,而不是使用保存在寄存器中的备份
B、可能用到volatile的地方:
a、并行设备的硬件寄存器(存储器映射的硬件寄存器加volatile,如:状态寄存器)
b、一个终端服务子程序中会访问到的非自动变量(中断服务程序中修改的供其他程序检测的变量需要添加volatile)
c、多线程应用中被几个任务共享的变量(各任务间共享的标志加volatile)
C、const和volatile区别:
const修饰的对象其值不能改变,而volatile修饰的对象其值可以随意的改变,也就是说,volatile对象值可能会改变,即使没有任何代码去改变它
4、const:C语言的一个关键字,他限定一个变量不允许被改变。
A、const只修饰其后的变量,至于const放在类型前还是类型后并没有区别。const int a和 int cosnt a都是修饰a为const
B、char const * pContent; //*pContent是const, pContent可变:*不是一种类型,即*pContent为从身体而pContent则是可变的
char* const pContent; //pContent是const,*pContent可变
C、int const *p1,p2;p2是const;//(*p1)是一整体,因此(*p1)是const,但p1可变
int const * const p1,p2;//p2是const,是前一个const修饰的,*p1也是被前一个const修饰,p1被后一个const修饰
int * const p1,p2;//p1是const,(*p1)是一个整体,所以const不修饰p2;
const在*的左边,则指针指向的变量的值不可变;在*的右边,则指针的指向不可变。“左定值,右定向”
D、const function(const)const,第一个const不允许修改返回值,第二个不允许修改参数值,第三个不允许修改类成员(C++)
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string; //1式,式子中*p1不能改变,p1可以改变
const pStr p2 = string; //2式,p2不能改变
5、union
A、共同体表示几个变量共同使用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。同一时间共同体中只能存储其中一个成员变量的值
B、小端模式(little_endian)/大端模式(big_endian):big,第一个字节是最高字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);little,第
一个字节是最低位字节(按照从低地址到高地址的顺序存储数据的低位字节到高位字节)。
6、static
A、全局变量/函数仅在单个c文件中访问,则可以将这个变量修改为静态全局变量/函数,以降低模块间的耦合度;
B、图全局变量仅在单个函数访问,则可以将这个变量改为函数的静态局部变量,以降低模块间的耦合度;
C、设计和使用访问动态局部变量、静态全局变量、静态局部变量的函数时需要考虑重入问题
7、typedef:为复杂的声明定义简单的别名,与auto、extern、mutable、static、register等关键字不能出现在同一个表达式中
typedef与define的用法经常出现混淆,看一下几个例子:
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
这里s1,s2,s3都是被声明为char *类型,但是s4被声明为char类型,因为define只是简单的替换而已。
typedef char * pStr;
const pStr p2 = string;
p2++;//这一句是错的,因为这里const 的意思是指将 pstr类型的值p2定义为只读的,而对于p2来说,它是一个char类型的指针,所以p2指针是只读的,这相当于char *const p2;
8、可重入代码
A、若一个程序或子程序可以安全的被并行,则称其为可重入的;即当该子程序正在运行时,可以再次进入并执行它,运行的结果不会互相干扰
B、若一个函数是可重入的,则该函数:不能含有静态(全局)非常量数据。不能返回静态(全局)非常量数据的地址。只能处理由调用者提供的数据。不能调用不可重入函数,多“用户/对象/进程优先级”以及多进程一般会使得对可重入代码的控制变得复杂。同时IO代码通常是不可重入的,因为他们依赖于像磁盘这样的共享的、单独的资源。
C、所有可重入函数都是线程安全的,但并非所有线程安全函数都是可重入的。
9、C程序组成:
代码段、cpu执行的机器指令部分;
初始化数据段(数据段),初始化了的全局变量;
非初始化数据段(bss段),程序中没有初始化的全局变量,内核将此段视为0;
变量位置:
栈,由编译器自动分配释放,存放函数的参数值,局部变量的值等,操作类似数据结构中的栈;
堆,由程序员分配释放,若程序员不释放,程序结束时肯那个由os回收,与数据结构中堆是不同的;
全局区(静态区),全局变量和静态变量存放在一块,初始化的全局变量和静态变量在一块区域(数据段),未初始化的在另一块区域(BSS段),程序结束时释放;
常量存储区,存放常量,程序结束时释放;
代码段、cpu执行的机器指令部分;
初始化数据段(数据段),初始化了的全局变量;
非初始化数据段(bss段),程序中没有初始化的全局变量,内核将此段视为0;
变量位置:
栈,由编译器自动分配释放,存放函数的参数值,局部变量的值等,操作类似数据结构中的栈;
堆,由程序员分配释放,若程序员不释放,程序结束时肯那个由os回收,与数据结构中堆是不同的;
全局区(静态区),全局变量和静态变量存放在一块,初始化的全局变量和静态变量在一块区域(数据段),未初始化的在另一块区域(BSS段),程序结束时释放;
常量存储区,存放常量,程序结束时释放;
更多嵌入式linux及编程学习交流的文章,请访问我的个人网站”恩享网” :http://www.enxiang.icoc.cc,期待与您共同进步。