老师不讲的C语言知识
关键字
auto
它可谓默默无闻,不少人应该知道它没什么用——局部变量默认就是auto类型。除此之外,auto变量存放在动态储存区中的栈区。也就是这种变量时有时无,寿命可变,自动(auto)管理。
指针
毫无疑问,指针是个麻烦事。比如char *(*(*(a[2])())()
是一个包含2个指向返回 指向字符的指针的函数指针的数组,几乎很难看出它到底是数组还是指针。
希望这些要点能帮到你!
优先与[]结合再与*结合
指针类型:把声明中指针名称去掉,就得到了指针的类型。
所指向的类型:去掉指针名称和一个*
指针赋值时,左边指针所指向的类型必须具有右边指针所指向类型的全部限定符,比如
char* cp; const char* ccp; ccp=cp;//正确 cp=ccp;//错误
函数
函数调用顺序
int a=f()+g()*h();
这三个函数的执行顺序是不确定的,C标准把选择顺序的权力交给编译器以便针对各个平台进行优化。
可以确定的一点是,乘法优先级高于加法。
参数压栈顺序:从右至左吗?
可能很多人都知道这个考点,函数参数压栈的顺序是从右至左,右边的表达式会先被运行。
重点在后面的问号
C标准对于压栈顺序并没有明确规定,也就是编译器可以修改成从左至右的压栈顺序。
默认的从右至左是为了支持可变参数,用来计算栈的大小。
确保你明白它们的用法、原理和......缺陷
早期的gets()
导致了蠕虫病毒,因为它不检查缓冲区是否越界,其实scanf也有这个问题。标准输入输出有许多设计上的细节需要被了解,比如printf使用%来转义%而不是\ , scanf里的\n
并不代表等待一个换行符而是读取并抛弃所有空格......
这些设计上的特点可能会在意想不到的地方产生出意想不到的效果。所以,为了程序的健壮性,多多了解它们吧。
预处理
#include能做些什么?
复制,原封不动的复制。
甚至可以这样:
//str.h
"hu","xiao","an"
//main.c
char arr[3][10]={
#include"str.h"
};
printf(a[1]);//输出xiao
真就是原封不动,但要注意预处理命令是要在一行的开头,独占一行。
如果是#include<>
则会首先在标准位置(C语言安装位置)搜寻,#include ""
则现在同一文件夹下搜索,找不到再去标准位置搜索。
#define不好吗?
在C++里,用#define来定义常量是不被推荐的,因为#define也仅仅是预处理替换,没有类型检查。
推荐使用const修饰的变量。仁者见仁,两种方法各有特点。
欢迎转载,请注明原文地址