指针
指针就是保存地址的变量,变量的值就是内存的地址。普通的变量的值是实际的值,指针变量的值是具有实际值的变量的地址。指针的常见错误:定义了指针变量,还没有指向任何变量,就开始使用指针。
*是一个单目运算符,用来访问指针的值所表示的地址上的变量;可以做右值也可以做左值。*的优先级低于++。
函数参数表中的数组实际上是指针;sizeof(a)==sizeof(int*),但是可以用数组的运算符[]进行计算。数组变量是特殊的指针;数组变量本身表达地址;int a[10];int*p=a;无需用&取地址,但是数组的单元表达的是变量,需要用&取地址。[]运算符可以对数组做,也可以对指针做:p[0]==a[0];运算符可以对指针做,也可以对数组做:*a=25;数组变量是const的指针,所以不能被赋值;int a[]==int* const a=……
指针是const:表示一旦得到了某个变量的地址,不能再指向其他变量。int* const q=&i
q是const; 所指是const:表示不能通过这个指针去修改那个变量(并不能使得那个变量成为const)。const int *p =&i;
可以把一个非const的值转化成const的值;当要传递的参数的类型比地址大的时候,这是常用的手段:既能用比较少的字节数传递值给参数,又能避免函数对外面变量的修改。
const数组:const int a[]={1,2,3,4,5,};数组变量已经是const的指针了,这里的const表明数组的每一个单元都是const int;所以必须通过初始化进行赋值。
保护数组值:因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值;为了保护数组不被函数破坏,可以设置参数const;int sum(const int a[],int length)。
给一个指针加一表示要让指针指向下一个变量;如果指针不是指向一片连续分配的空间,如数组,则这种运算没有意义。这些算数运算可以对指针做:给指针加、减一个整数(+,+=,-,-=);递增递减(++/--);两个指针相减。
0地址:当然你的内存中有0地址,但是0地址通常是个不能随便碰的地址;所以你的指针不应该具有0值;因此可以用0地址来表示特殊的事情:返回的指针是无效的,指针没有被真正初始化(先初始化为0);NULL是一个预定定义的符号,表示0地址;有点编译器不愿意你用0来表示0地址。
不同类型的指针是不能直接相互赋值的。
指针的类型型转换:void*表示不知道指向什么东西的指针;计算时与char*相同(但不相通);指针也可以转换类型int *p=&i;void*p=(void*)p;这并能没有改变p所指的变量的类型,而是让后人用不同的眼光通过p看它所指的变量;我不再当你是int啦,我认为你就是个void。
用指针做什么:需要传入较大数据时用作参数;传入数组后对数组做操作;函数返回不止一个结果;需要用函数来修改不知一个变量;动态申请的内存。
malloc:#include<stdlib.h>
Void* malloc(size_t size);
向malloc申请的空间的大小是以字节为单位的;返回的结果是void*,需要类型转换为自己需要的类型; (int*)malloc(n*sizeof(int))
free() 把申请得来的空间还给“系统”;只能还申请来的空间的首地址。