1、数组与指针的区别,见程序:
#include <stdio.h>
void func(int pdata[])
{
printf("sizeof(pdata)=%d\n",sizeof(pdata));
}
int main()
{
int data[3] = {1,2,3};
printf("data=0x%x &data=%p\n",data,&data);
printf("data+1=0x%x &data+1=%p\n",data+1,&data+1);
printf("sizeof(data)=%d sizeof(&data)=%d\n",sizeof(data),sizeof(&data));
func(data);
return 0;
}
./a.out
data=0xff901374
&data=0xff901374
data+1=0xff901378
&data+1=0xff901380
sizeof(data)=12
sizeof(&data)=4
sizeof(pdata)=4
可见,data与&data的地址是一样的,但是data+1与&data+1却不同,这是因为data是个指针,加一指向数组下一个元素,而&data加一则指向数组外的元素,加的是整个数组的大小。在函数中,传的是数组,但传到函数里又变成了指针。
2、char* const a[] 与 const char* a[] 的区别,第一个表示指针是不可修改的,第二个表示内容不可修改;
3、“指针类型”、“指针类型变量”、“指针类型的值”经常被简单的统称为“指针”,所以很容易造成歧义,需提高警惕;
4、所谓指针类型的值,实际是指内存的地址 ;
5、对指针变量运用 * 运算符,就等同于它指向的变量。如果a_p指向a,*a_p就等同于a;
6、对指针加N,指针前进“当前指针指向的数据数据的长度×N”;
7、空指针是指 可以确保没有指向任何一个对象的指针,通常使用宏定义NULL来表示空指针常量值。空指针确保它和任何非空指针进行比较都不会相等,因此经常作为函数发生异常时的返回值使用;
8、给指向数组的某个元素的指针加N后,指针会指向N个之后的元素;
9、“在C中,如果在数组名后不加[],单独的只写数组名,那么此名称就表示 指向数组初始元素的指针”这个说明是错误的;p[i]只不过是 *(p+i) 的简便写法,除此之外,它毫无意义,下表运算符原本只有这种用法,和数组无关。在表达式中,数组可以解读成“指向它的初始元素的指针”,与在后面加不加[]没有关系;但在声明中,[] 还是表达数组的意思。因此 p[i] 可以写成 i[p],并且对结果毫无影响;
10、在C中,是不能将数组作为函数参数进行传递的。但是,可以通过传递指向初始元素的指针来达到将数组作为参数进行传递的目的。在函数中,之所以可以像p[i]这样操作p的内容,是因为 p[i]是 *(p+i) 的语法糖;
11、用声明函数形参的方法传递数组时。只有在声明函数形参时,数组的声明才可以被解读为指针,比如,对于 int func(int a[]) ,编译器可以针对性地解读成: int func(int *a),下面声明的形参,都具有相同的意义:
int func(int *a) //后两个都是语法糖
int func(int a[])
int func(int a[10]) //这里即使定义了元素个数,编译器也是无视的
12、虚拟环境。当今的操作系统都会给应用程序的每一个分配独立的“虚拟地址空间”。这和C语言本身并没有关系,而是操作系统和CPU协同工作的结果。所以通过printf打印指针的时候,输出的并不是物理内存地址本身。
13、添加static后,作用域就只限定在当前所在的源代码文件中,通过static指定的变量(包括函数),对于其他源代码文件是不可见的;
14、C语言中有三种内存领域的寿命。
①静态变量的寿命从程序运行开始,到程序关闭结束;
②自动变量的寿命到声明该变量的语句块执行结束为止;
③通过malloc()分配的领域的寿命到调用free()为止;
15、大多数操作系统中,都将函数自身和字符串常量被配置在一个只读内存区域的;
16、如果需要通过函数返回值之外的的方式返回值,将“指向T的指针” (如果想返回的值的类型为T) 作为参数传递给函数;
17、