21、关键字volatile有什么含意? 并给出三个不同的例
子。
【参考答案】一个定义为volatile的变量是说这变量可
能会被意想不到地改变,这样,编译器就不会去假设
这个变量的值了。精确地说就是,优化器在用到这个
变量时必须每次都小心地重新读取这个变量的值,而
不是使用保存在寄存器里的备份。下面是volatile变量
的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量
(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
22、嵌入式系统经常具有要求程序员去访问某特定的
内存位置的特点。在某工程中,要求设置一绝对地址
为0x67a9的整型变量的值为0xaa66。编译器是一个纯
粹的ANSI编译器。写代码去完成这一任务。
【参考答案】这一问题测试你是否知道为了访问一绝对
地址把一个整型数强制转换(typecast )为一指针是合
法的。这一问题的实现方式随着个人风格不同而不同
。典型的类似代码如下:
int * ptr;
ptr= (int *)0x67a9;
*ptr = 0xaa55;
23、头文件中的ifndef/define/endif 干什么用?
【标准答案】防止该头文件被重复引用。
24、#include
#define swap(x, y) (x)=(x)+(y);(y)=(x)–(y);(x)=(x)–(y);
#define swqp(x,y) (x)=(x)-(y);(y)=(x)+(y);(x)=-((x)-(y));
33、写一个“标准”宏,这个宏输入两个参数并返回较
小的一个。
【标准答案】#define Min(X, Y) ((X)>(Y)?(Y):(X))// 结尾
没有;
34、带参宏与带参函数的区别(至少说出5点)?
【标准答案】
带参宏 带参函数
处理时间 编译时 运行时
参数类型 无 需定义
程序长度 变长 不变
占用存储空间 否 是
运行时间 不占运行时间 调用和返回时占
35、关键字volatile有什么含意?
【标准答案】提示编译器对象的值可能在编译器未监测
到的情况下改变。
36、int main()
{
int x=3;
printf(“%d”,x);
return 1;
}
问函数既然不会被其它函数调用,为什么要返回1?
【标准答案】mian中,c标准认为0表示成功,非0表示
错误。具体的值是某中具体出错信息。
37、已知一个数组tabl e ,用一个宏定义,求出数据的
元素个数。
【标准答案】
#define NTBL(table) (sizeof(table)/sizeof(table[0]))
38、A.c 和B.c两个c文件中使用了两个相同名字的
static变量,编译的时候会不会有问题?这两个static变量
会保存到哪里(栈还是堆或者其他的)?
【标准答案】static的全局变量,表明这个变量仅在本
模块中有意义,不会影响其他模块。
他们都放在静态数据区,但是编译器对他们的命名是
不同的。
如果要使变量在其他模块也有意义的话,需要使用
extern 关键字。
39、static全局变量与普通的全局变量有什么区别?
【标准答案】 static全局变量只初使化一次,防止在其
他文件单元中被引用;
作用域,static全局变量限制为当前文件中。
40、static局部变量和普通局部变量有什么区别
【标准答案】static局部变量只被初始化一次,下一次
依据上一次结果值;
存储域,static局部变量被存储在静态数据区,而普通的则存在栈区。
41、static函数与普通函数有什么区别?
【标准答案】static函数在内存中只有一份,普通函数在
每个被调用中维持一份拷贝。
作用域,static函数限制为当前文件中。
知识提要:
C语言内存分区_栈区、堆区、全局&静态区、文字常量区、程序代码区
C语言开发对内存使用有区域划分,分别是栈区、堆区、全局&静态区、文字常量区、程序代码区。注意此处的栈、堆名称有别于数据结构中栈与堆的概念。栈与堆的英文名分别为stack与heap。
栈区:
在函数中定义的变量存放的内存区域。
常见的int、float、char等变量均存放于栈区中,它的特点是由系统自动分配与释放,不需要程序员考虑资源回收的问题,方便简洁。
ps:栈区的地址分配是从内存的高地址开始向地地址分配。
堆区:
程序员通过指令自主向系统申请的内存区域,大小由程序员决定,它在使用完后同样需要程序员通过指令去释放该区域内存,否则将有可能出现内存的浪费与溢出。
C语言中申请堆区指令为:
int p = (int ) malloc( N * sizeof(int) ); //分配N个int型(4字节)的内存,即 4 * N 个字节
ps:但指针p存放于栈区。
C语言中释放堆区指令为:
free( p ); //注意此处参数为指针
使用中应该注意,尽量不要去修改p指针对应的地址值,否则在内存释放时将出现错误。(编译可通过,运行出现问题)
全局变量&静态变量区:
全局变量与静态变量本应是两个概念,但由于它们在内存中存放的区域相同,所以将他们放在一起讨论。
全局变量:
位于所有函数外部定义的变量,在整个工程中可见,可修改。
静态变量:
位于所有函数内部定义的由 static 修饰的变量,仅在定义的函数中可见,可修改。(这是它与全局变量的关键区别)
ps:静态变量仅在第一次创建时初始化一次,之后自动跳过初始化语句。
全局变量与静态变量均由系统分配和释放内存,若未对它们进行初始化操作,系统将自动将其值设置为0。(堆区与栈区则不会)
文字常量区:
用于存放文字等不可修改的常量,由系统分配和释放内存。
常见的使用:
char *s = “HelloWorld”;//该字符串 HelloWorld 即存放于文字常量区,不可修改
ps:但指针s存放于栈区。
pps:若在程序中尝试对其修改(例如尝试修改第一个字符 *s = ‘h’;),将出现编译可通过,运行报错的情况。
同时因注意它与const修饰的变量之间的区别:
char aa = ‘A’;//aa存放于栈区
const char bb = ‘B’; //bb同样存放于栈区
const修饰的变量仅仅用于告诉编译器bb是一个常量,如果后续的程序中有出现尝试修改bb的操作时,编译将报错。
这种写法主要是为了防止程序员在后续的代码中误操作bb变量而添加的一个约束条件,并不会影响它存放的位置。
程序代码区:
用于存储程序编译连接后生成的二进制机器码指令的内存区域。该部分内容可通过反汇编操作将机器码转换为汇编语言。