一:define和const的区别
1:define是预编译阶段
const常量是编译运行阶段使用
define是宏定义,程序在预处理阶段将用define定义的内容进行替换,因此程序运行时常量表中并没有用define定义的常量,系统不为其分配内存。
const常量是编译运行时的常量,系统为其分配内存。
2.类型跟安全检查不同
define宏没有类型,不做任何类型检查,仅仅是展开
const常量有具体的类型,编译运行时会执行类型检查
3.存储方式不同
define仅仅是展开,有多少地方使用就展开多少次,不分配内存
const常量会在内存中分配(可以在堆中也可以在栈中)
4.const可以节省空间,避免不必要的的内存分配。
define注意“边缘效应”,
例:#define N 2+3 //N的值是5
int a = N/2,//在编译时我们预想a=2.5,实际打印结果是3.5
原因是在预处理阶段,编译器将a=N/2处理成a=2+3/2,这就是define宏的边缘效应;
所以我们应该写成#define N (2+3)
二:数组
1.C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来
2:对于一个数组,我们可以获得指向该数组下标为0的元素的指针。一数组下标进行的运算也都是通过指针进行的
三:字符’0’,字符’\0,整数0
字符’0’:char c = ‘0’; 它的ASCII码实际上是48。内存中存放表示:00110000
字符’\0’ : ASCII码为0,表示一个字符串结束的标志。这是转义字符。
整数0 :ASCII码为0,字符表示为空字符,NULL;数值表示为0;内存中表示为:00000000
四:arr和&arr
arr是数组首元素的地址
&arr是数组的首地址
C语言是存在数组类型的,对没错是数组类型,而这个类型在大多数情况下会隐式转换为它的元素的指针类型,所以你定义了一个数组int arr[10],arr的类型实际上是int[10],但是因为大部分情况下的隐式转换,arr的类型会退化为int*大部分情况下都会发生隐式转换,不会发生隐式转换的情况有三个,sizeof运算的时候,取地址(&)运算的时候,字符串常量初始化的时候,这也就是为什么sizeof数组是整个数组的长度,不等于sizeof指针,在此我不想讨论C为什么要做这么多隐式转换。上面说&运算的时候不会发生隐式转换,所以&arr,就是取arr数组的地址,取数组的地址,注意我的用词,既不是取数组名的地址,也不是取数组首元素的地址,arr就是数组,&arr就是取数组的地址,也就是整个数组在内存中的第一个位置的地址,这个运算结果的类型是数组的指针,也就是int()[10]。arr的值在很多情况下会隐式转换为首元素地址,所以你在问题描述里就认为它就是首元素地址(但其实不是)&arr是数组的地址,碰巧和首元素地址相同但是他们类型不同,一个是int[10]隐式转换成的int,另一个是int(*)[10]