- 日期:20160608
- 作者:i.sshe
- https://github.com/isshe
C语言相关问题
1. 基本问题
- 1.1 const知多少?
- 1.2 static知多少?
- 1.3 sizeof知多少?
- 1.4 volatile是什么?有何用?
- 1.5 哪些库函数是不安全函数?点解?
- 1.6 C语言中,预处理指令是否是语言类型(语句)?
- *
2.拓展问题
- 2.1 常量知多少?
- 2.2 不用sizeof, 如何判断系统32位或16位?
3. 基本问题解答
3.1 const知多少?
- const关键字不能把变量变成常量。(而《C和指针》中说:可以使用const关键字来声明常量)【下文用代码验证】
- const最常用于“参数的传递”, 也是最有之处(限定函数的形参)。
- const限定变量,则变量的值不能改变;限定数组, 则数组的所有元素的值都不能改变。
- 修改const限定的变量的值,所产生的后果取决于具体的实现。
- 代码:
#define DENUM 10
enum enn{
ENNUM = 10
};
int main(void)
{
const int num = 10;
int arrayconst[num]={0};
int arrayenum[ENNUM]={0};
int arraydefine[DENUM]={0};
return 0;
}
- 编译会出错:
- As we all know,数组的长度只能用“常量”。而常量有两种,见拓展问题。
3.2 static知多少?
- 当static用于函数定义或代码块之外的变量声明时,函数或变量只能在文件内使用。(连接属性从external变为internal)
- 当用于代码块内部时,修饰的变量生命周期和程序一样长,但是作用域不变。(变量被保存在数据段而不是栈(局部变量保存栈上))
- 为什么static变量只初始化一次?存放在静态区的变量的生命周期一般比较长, 一般与整个程序“同生死,共存亡”。
在头文件中定义静态变量是否可行?不可行,因为如果在使用了该头文件的每个C文件中定义了静态变量,按照遍历的步骤, 每个头文件都会单独存在一个静态变量,从而引起空间浪费或程序错误。
注意:
- 声明在函数外的全局变量,存储类型为静态变量,存在数据段而不是堆栈。
3.3 sizeof知多少?
- sizeof是数据类型的关键字。
- 图:《程序员面试笔试宝典第二版》 4.3.1 p68.
- sizeof(“\0”)=2!!! //strlen(“\0”)=0;
3.4 volatile是什么?有何用?
- 是一个类型修饰符(type specifier)
- 编译器不会对它修饰的变量进行优化。(优化是指:为提高存取速度,把变量放cache或寄存器,以便更快地访问。)
- 多线程程序中,如果一个线程把某变量放到cache/寄存器中,而其他线程改变了该变量,此线程再从cache/寄存器读取就会出现问题。而如果用了volatile,则程序会每次都从内存读取此变量。(小心翼翼地)
- volatile修饰的变量告诉编译器:此变量可能会被意想不到地改变,不要假设它的值,不要优化它。
3.5 哪些库函数是不安全函数?点解?
- 最常用的一些举例:
- strcpy(): 将源字符串复制到缓冲区。没有指定复制字符的具体数目,可能会造成缓冲区溢出。【替代函数:strncpy】
- strcat(): 类似于 strcpy(),将一个字符串合并到缓冲区末尾。同样容易造成溢出。【替代函数:strncat】
- sprintf(): 用来格式化文本并将其存入缓冲区的通用函数。和strcpy()类似。
- gets(): 从标准输入读入用户输入的一行文本,在遇到 EOF 字符或换行字符之前,不会停止读入文本。不执行边界检查。因此,容易造成缓冲区溢出。【替代函数为:fgets】
- 图片来源:http://blog.csdn.net/uniquecapo/article/details/38235149
3.6 C语言中,预处理指令是否是语言类型(语句)?
- 不是。
- C语言的语句有五种:
- 表达式语句;
- 函数调用语句;
- 控制语句;(选择,循环)
- 复合语句;
- 空语句;
4. 拓展问题解答
4.1 常量知多少?
- 根据《C程序设计语言(K&R)》,常量有3种使用方式:
- 符号常量:#define name text
- #define aaa (bbb)
- 直接使用整型常量、浮点型常量、字符串常量…
- 123, 123.4, “abcd”
- 枚举常量:enum;
- enum boolean{NO, YES};
- enum escapes{B=’\a’, T=’\t’, N=’\n’};
- 符号常量:#define name text
2 不用sizeof, 如何判断系统32位或16位?
int main(void)
{
unsigned int a = ~0;
if (a > 65536)
printf("32 or 64\n");
else
printf("16\n");
}
return 0;
- 判断64/32位以及主机字节序:
5.参考资料
- 5.1 《C专家编程》
- 5.2 《C程序设计语言(K&R)第二版》
- 5.3 《C和指针》
- 博客:http://blog.csdn.net/uniquecapo/article/details/38235149