C语言学习 指针总结
1、理解指针
指针 | 指针变量,内存会为指针变量开辟空间,存地址编号 |
---|---|
地址 | 内存以字节为单位进行管理,1个字节1个编号,内存开空间的时候首字节的地址编号 |
空间 | 存储数值的内存空间, 地址+数据类型确定一个空间 |
值和地址
int a = 30;
//值: 30 -- %d
//地址:&a -- %p
2、指针定义
*指向对象的数据类型 指针名;
int a = 30;
int *p = &a; //p是定义的指针变量,存储了变量a在内存中的地址
//指针保存谁的地址就指向谁,指向谁就保存谁的地址
例:
定义两个变量a和b,给a和b赋值。
定义一个指针先指向a,通过指针访问a的地址和值。
再讲指针指向b,访问b的地址和值。
int a = 30;
int b = 50;
int *p = &a; //指针变量p指向a,保存a的地址
printf("%p %d",p,*p); //输出 -- a的十六进制地址 30
p = &b;
printf("%p %d",p,*p); //输出 -- b的十六进制地址 50
3、指针操作内存空间
指针本身的空间 | 指针名 |
---|---|
指针指向的空间 | *指针名 |
ps:指针定义时候的 * – 代表指针的标记,即告诉编译器我创建的是一个指针变量
指针使用的时候 * – 代表 解地址
int a = 30;
int* p; // *--- 指针标记
p = &a;
*p = 20; // * --- 解地址 --- 解完之后得到的是指针指向空间
//也可以理解为 *p就是a
//可以通过代码验证
int res = *p == a ? 1 : 0;
printf("%d",res); //输出 -- 1
4、指针的空间大小
sizeof函数可以返回数据类型或变量所占的字节大小
int *p;
char *ch;
float *t;
printf("%d",sizeof(int*)); //输出 -- 34位输出4 64位输出8
printf("%d",sizeof(char*)); //输出 -- 34位输出4 64位输出8
printf("%d",sizeof(float*)); //输出 -- 34位输出4 64位输出8
由此可见 指针空间大小和指向对象的数据类型无关,因为指针变量只存首地址。
5、指针的偏移
指针可以指向一块连续的空间,通过指针偏移对空间进行读写操作。
int a[5] = {4,8,10,29,4};
*int p = a; // p指向a[0] p = &a[0]
p ---- &a[0]
p+1 ---- &a[1]
p+2 ---- &a[2]
通过代码验证:
int a[5] = {1,2,3,4,5};
int *p = a;
printf("%p %p %p %p %p",&a[0],&a[1],&a[2],&a[3],&a[4]);
printf("%p %p %p %p %p",p,p+1,p+2,p+3,p+4);
//执行后可以看到 两个输出的地址值是相同的.
指针的偏移和指向对象的数据类型有关
以指向对象的数据类型为单位进行偏移
指向对象的数据类型:从指针的定义上看。
两个指针相减
//在数组在里面
int a[5] = {80,45,7,100,20};
int *p = a;
int *q = &a[3];
printf("%d\n",q-p); // 输出 -- 3
// 指向数组里面的元素的指针相减 = 元素下标之差
6、指针的 ++ – 操作
int a[5] = {90,100,34,67,8};
// 指针偏移来操作
int *p = a;
printf("%d %d %d %d %d\n",*(p+0),*(p+1),*(p+2),*(p+3),*(p+4));
//此时指针p的指向没有改变
------------------------------------------------------------------------
// 指针++
int *q = a;
printf("%d ",*q); //输出 -- 90
q++; // q = q + 1; //指针q的指向改变 指向 -> &a[1]
printf("%d ",*q); //输出 -- 100
q++; // q = q + 1; // &a[2]
printf("%d ",*q); //输出 -- 34
------------------------------------------------------------------------
int a[5] = {90,100,34,67,8};
int *t;
for(t=a;t<=&a[4];t++) //t赋初值 == a[0]的首地址
{ //a[4]的地址作为结束条件 每次循环t+1,指向数组下一个元素的地址
printf("%d ",*t); //输出 -- 90 100 34 67 8
}