1.指针
在计算的存储器中有很多的存储单元,我们的操作系统把这些存储单元以字节为单位进行编号,也就是每个存储单元(字节),都有编码。这些编码在我们内存中就称为地址。一个字节有八位,位是存储信息的最小单位,字节是存储单元的基本单位。
指针就是地址;指针变量就是存放别人的地址的变量。(指针就是用来放地址的)
一级指针存放整型,浮点型,字符型,数组,函数。
那么一级指针存放别人的地址,它本身有地址吗?
答案是有的,我们专门用二级指针来存放一级指针的地址。
二级指针是存放一级指针的地址。那么二级指针也是有地址的,我们就有三级指针。
注意我们的一级指针跟二级指针的类型也要匹配。
c语言中相同符号有不同的含义
int *p; //此处的*p 是表示指针标记
int a = 3; p=&a;//指针初始化
*p = 30;//此处的*p 是解引用,取目标操作符 在c语言中相同的操作符是有着不同的含义的。
int *(*q);//此处的*q 跟上面的*p是一样的,都是指针的标记。定义一个二级指针 而int * 是类型,这样的理解就是q是一个指针,指针int *类型。
2.指针的偏移理解
类型+数组名+n,偏移量是类型的字节大小。 例如 int a[4], a+1标识a代表首元素的地址偏移四个字节;*(a+1) 等价于a[1]; 一次是偏移四个字节,也就是一个整型。
char a[4], a+1标识数组名a代表首元素的地址偏移一个字节,也就算是一个char型。
那么,我们char型跟int型之间要怎么转换呢,我们可以用一个指针指向char型数组,然后对指针进行偏移。
如果是int a[3] = {1,2,3};
int (*p)[3] = &a;
p,&a,a三者表示的地址是一样的,但它们表示的含义是不一样的。
1.p表示想系统申请一块空间存储了数组a这这块内存空间的地址
2.&a表示数组a这块内存空间取地址
3.a在这里表示首元素地址
p+1 //表示数组名a代表的首地址整体的偏移12个单位,因为要偏移三个整型,所以就是偏移12个字节。
#include <stdio.h> //指针的偏移
int main()
{int a[3] = {1, 2, 3}; // 初始化一维数组int *p = a; // 等价于 p = a;printf("%p\n", a);// printf("%p\n", a);// printf("%p\n", p);// printf("%p,%d\n", p + 1, *(p + 1));// printf("%p,%d\n", p + 2, *(p + 2));// printf("---------------------\n");int(*q)[3] = &a; // 类型匹配 int [3] 存放数组a的地址printf("%p\n", a);printf("%p\n", q);q = &a;// char *qq = p;printf("%d\n", **q);printf("---------------------\n");printf("%p\n", *q); // q == &a; *q == a &a跟a的地址都是首元素的地址。// 但是&a 跟 a 两个+1的偏移量是不同的printf("%p\n", a);printf("---------------------\n");printf("%p\n", q);printf("%p\n", a+1);printf("%p\n", q+1);char *qq = p;printf("%d\n", *qq);return 0;
}