1.指针的由来
指针就是地址,地址你应该明白吧,比如说你要买个快递,你得要有地址,没有地址的话人家怎么给你送货上门,地址里面放的是自己家的详细信息,这样快递员才会根据你提供的地址送货上门并且找到你。
比如说你要去找一个朋友玩,你得要有朋友的地址啊,不然怎么能找到朋友,地址里面放的是朋友家的详细地址信息,通过朋友家的地址找到朋友,这就是地址,而指针也是一样,不过里面放的是数据,通过地址找到里面存放的数据,这就是指针。
计算机里面的地址是怎么来的呢,在我们的计算机当中有地址线,地址线每次通电断电都会有变化产生0和1,所以一个地址线有两种状态。而我们的计算机分为32位和64位,32位有32根地址线,64位有64根地址线,32位地址线会产生2的32次方个地址,每个地址的都有一个编号,地址编号从0到2的32次方-1,64位是0到2的64次方-1,这就是计算机地址的由来,也就是指针的由来。
2.怎么获取地址
c语言中我们该怎么获取地址,获取地址之后用什么来存放地址,在c语言中有一个单目操作符“&”,这个操作符只有一个操作数,我们可以使用它来获取地址,如下所示:
#include<stdio.h>
int main()
{
int a = 10;
&a;
return 0;
}
现在已经取出了地址我们可以创建一个指针变量来存放地址,如下所示:
#include<stdio.h>
int main()
{
int a = 10;
char c = 20;
short s = 15;
int* p = &a; //*表示这是一个指针,p表示指针的变量名,int表示p指向的是一个int类型的数据
char* pc = &c; //*表示这是一个指针,pc表示指针的变量名,char表示pc指向的是一个char类型的数据
short* ps = &s; //*表示这是一个指针,ps表示指针的变量名,short表示ps指向的是一个short类型的数据
printf("%p\n", p);
printf("%p\n", pc); // %p专门用来打印地址的占位符 地址以16进制形式打印
printf("%p\n", ps);
return 0;
}
2.1 怎么获取地址中的数据
取地址也有一个操作符“*”,在有两个操作数的时候它是乘法运算符,在只有一个操作数的时候它是解引用操作符,如下所示:
3.指针运算
我们知道整型有加减乘除以及取余,而指针也就是地址也有它们的计算方式,分别是:地址加减整数,地址-地址,两个地址比大小。
3.1 地址加减
地址可以对整数进行加减,对整数加减而言,加减的是指针所指向对象的类型所占空间的字节,而不是单单一个整数,如下所示:
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a;
printf("自增之前 = %p\n",p);
p = p + 1;
printf("自增之后 = %p\n", p);
return 0;
}
为什么这两个地址之间相差4个字节呢,这是因为指针变量p所指向数据的类型是int类型,所占内存空间大小为4个字节,每次加1或减1都是加减(整型*指针变量所指向的数据的类型大小),如下所示:
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a; //指针变量p所指向的对象的数据类型是int类型,在内存空间占4个字节
printf("--------------------------------------\n");
printf("(int *)地址自增之前 = %p\n",p);
p = p + 1; // p = p + 1 * 4(指针p指向对象为int类型,在内存空间占4个字节大小)
printf("(int *)地址自增之后 = %p\n", p);
printf("--------------------------------------\n");
//printf("\n");
char c = 'a';
char* pc = &c; //指针变量pc所指向的对象的数据类型是char类型,在内存空间占1个字节
printf("(char *)地址自增之前 = %p\n", pc);
pc = pc + 1; // pc = pc + 1 * 1(指针p指向对象为char类型,在内存空间占1个字节大小)
printf("(char *)地址自增之后 = %p\n", pc);
printf("--------------------------------------\n");
//printf("\n");
short s = 20;
short* ps = &s; //指针变量ps所指向的对象的数据类型是short类型,在内存空间占2个字节
printf("(short *)地址自增之前 = %p\n", ps);
ps = ps + 1; // ps = ps + 1 * 2(指针p指向对象为short类型,在内存空间占2个字节大小)
printf("(short *)地址自增之后 = %p\n", ps);
printf("--------------------------------------\n");
return 0;
}
3.2 地址-地址
地址也可以减去地址,但前提条件是两个地址都指向同一块空间,这样地址-地址才有意义,他们之间的值是两个地址之间相差的元素个数,如下所示:
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr; //arr表示数组首元素地址 除了sizeof(数组名) 计算整个数组的大小,单位字节。和 &数组名取的是整个数组的地址,其它地方的数组名都是数组首元素的地址
int* pa = &arr[9]; //取出数组最后一个元素的地址
printf("%d\n", pa - p); // 计算它们之间的元素个数
return 0;
}
PS.单独放一个数组名表示数组首元素地址 , 除了sizeof(数组名) 计算整个数组的大小 和 &数组名取的是整个数组的地址,其它地方的数组名都是数组首元素的地址,这个知识点是学好指针必要的。
3.3 地址和地址进行比大小
地址和地址之间可以进行比较大小,可以用来当作条件,如下所示:
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr;
int* pa = &arr[9];
while (p <= pa)
{
printf("%d ", *p); // 通过地址来遍历打印数组的所有元素
p++;
}
return 0;
}
结语
希望这篇关于指针的文章能够对大家有所帮助,欢迎各位大佬留言或者私信与我交流。