指针的本质就是地址
#include <stdio.h>// 指针int main(){int i = 5;// &是(引用)取地址 指针变量的初始化一定是某个变量取地址int *i_pointer = &i;// || *是解析地址 如果只是 i_pointer 就是其存的地址printf("%d\n", *i_pointer);return 0;}
指针传递
#include <stdio.h>void change(int *j) // j 形参 j=&i{*j = 5;}// 指针传递int main(){int i = 10; // i 局部变量printf("before change , i = %d\n", i);change(&i); //函数调用时,把&i称为实参printf("after change , i = %d\n", i);return 0;}
指针偏移
前面介绍了指针的传递。指针即地址,就像我们找到了-栋楼,这栋楼的楼号是B,那么往
前就是A,往后就是C,所以应用指针的另一个场景就是对其进行加减,但对指针进行乘除是没
有意义的,就像家庭地址乘以5没有意义那样。在工作中,我们把对指针的加减称为指针的偏移,
加就是向后偏移,减就是向前偏移。
#include <stdio.h>// 指针偏移int main(){int a[5] = {1,2,3,4,5};int *p; //对一个指针变量进行取值,得到的类型是其基类型p = a;for (int i = 0; i < 5; i++){/* 先偏移在取地址 */printf("*p = %d \n", *(p + i));}return 0;}
指针自增自减
#include <stdio.h>// p[0] = *p// 指针自增int main(){int a[3] = {2, 5, 8};int *p;int j;p = a; // 让指针变量p,指向数组的开头// j = *p++;j = *p;p++;printf("a[0] =%d,j =%d,*p =%d\n", a[0], j, *p); // 2,2,5// j = p[0]++;j = *p;printf("之前的*p =%d\n", *p);printf("之前的a[1] =%d\n", a[1]);// *p++ 指的是这个空间向前加一位 (*p)++ == p[0]++这个地址里面的数加一*p++;printf("之后的*p =%d\n", *p);printf("之后的a[1] =%d\n", a[1]);printf("a[1] =%d,j =%d,*p =%d\n", a[1], j, *p); // 6,5,6return 0;}
指针与一维数组
一维 数组在函数调用进行传递时,它的长度子函数无法知道
数组名作为实参传递给子函数时,是弱化为指针的
#include <stdio.h>void change(char *d){*d = 'H';d[1] = 'E';// 等于上面的操作// *(d + 1) = 'E';*(d + 2) = 'L';}// 指针与一维数组int main(){char c[10] = "hello";change(c);puts(c);return 0;}
指针与动态内存申请
C语言的数组后会觉得数组长度固定很不方便,其实C语言的数组长度固定是因为其定义的整型、浮点型、字符型变量、数组变量都在栈空间中,而栈空间的大小在编译时是确定的。如果使用的空间大小不确定,那么就要使用堆空间。
程序是放在磁盘上的有序的指令集合
