以下是本人对于指针的理解
计算机把地址当作整数来处理,可以简单的认为指针就是整数,这个整数是数据的存储地址
我这里是64位的操作系统,指针是8字节整数,32位系统应该是4字节
可以简单认为指针,就是8字节整数
struct testStruct
{
int a;
double b;
};
int main(void)
{
int* a = nullptr;
printf("int型指针 a的大小为 %d 字节\n", sizeof(int*));
double* b = nullptr;
printf("double型指针 b的大小为 %d 字节\n", sizeof(int*));
testStruct* c = nullptr;
printf("testStruct型指针 c的大小为 %d 字节\n", sizeof(int*));
return 0;
}
这个8字节整数是数据的存储地址
因此本人喜欢
int* pi;
double* pd;
这样的声明格式
int a = 5;
int* pa = &a;
//输出存储地址推荐格式控制符%p 当然十六进制长整型%#lX啥的也没问题
printf("int变量 a = %d,int变量a的存储地址是 %p\n",a,&a);
printf("利用指向a的指针pa再次打印上述内容\n");
printf("pa指向的内容 *pa = %d,指针pa本身为 %p\n", *pa, pa);
printf("\n\n");
double b = 3.14;
double* pb = &b;
printf("double变量 b = %lf,double变量b的存储地址是 %#lX\n", b, &b);
printf("利用指向b的指针pb再次打印上述内容\n");
printf("pb指向的内容 *pb = %lf,指针pb本身为 %#lX\n", *pb, pb);
运行以上代码
![!在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a4e095d45624474fb0f07cf7ec9af7ba.png)
如果要将数字值地址来使用,应通过强制类型转换将数字转换为适当的地址类型
int* pt = NULL;
pt = (int*)0XB8000000;
对于指针与整数相加减,与其说是加减不如说是往前后移动
比如
int testIntArray[10] = { 0,1,2,3,4,5,6,7,8,9 };
int* pInt = testIntArray;
pInt += 5;
大家肯定是想让它往后移动5个元素,而不是代表地址的数字+5
因此实际上,代表地址的数字增加了5*sizeof(int)
其它的也类似
++代表右移动1
–代表左移动1
测试代码
#include<stdio.h>
struct testStruct
{
int a;
double b;
};
int main(void)
{
printf("int型数据大小为 %d 字节\n", sizeof(int));
int testIntArray[10] = { 0,1,2,3,4,5,6,7,8,9 };
int* pInt = testIntArray;
printf("当前 pInt指针指向的内容为:%d pInt指针本身为:%p\n", *pInt, pInt);
printf("pInt指针右移5\n");
pInt += 5;
printf("当前 pInt指针指向的内容为:%d pInt指针本身为:%p\n", *pInt, pInt);
printf("\n\n");
printf("double型数据大小为 %d 字节\n", sizeof(double));
double testDoubleArray[10] = { 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.1 };
double* pDouble = testDoubleArray+5;
printf("当前 pDouble指针指向的内容为:%lf pDouble指针本身为:%p\n", *pDouble, pDouble);
printf("pDouble指针左移3\n");
pDouble -= 3;
printf("当前 pDouble指针指向的内容为:%lf pDouble指针本身为:%p\n", *pDouble, pDouble);
printf("\n\n");
printf("我用来测试的结构体testStruct型数据大小为 %d 字节\n", sizeof(testStruct));
testStruct testStructArray[5] = { (0,1),(2,3),(4,5),(6,7),(8,9) };
testStruct* pStruct = testStructArray;
printf("当前 pStruct指针指向的内容为:%d %lf pStruct指针本身为:%p\n", pStruct->a, pStruct->b, pStruct);
printf("pDouble指针右移2\n");
pStruct = pStruct+2;
printf("当前 pStruct指针指向的内容为:%d %lf pStruct指针本身为:%p\n", pStruct->a, pStruct->b, pStruct);
return 0;
}
结果如图,注意一下,后面是16进制数,结果是没有问题的
同样的,两个指针相减,代表相对移动了多少,而不是数字相减
printf("int型数据大小为 %d 字节\n", sizeof(int));
int intArray[9] = { 0,1,2,3,4,5,6,7,8 };
int* start = intArray;
printf("start指针指向的内容为:%d start指针本身为:%p\n", *start, start);
int* end = intArray + 8;
printf(" end指针指向的内容为:%d end指针本身为:%p\n", *end, end);
printf("end-start结果为%d", end - start);
其它杂项
一个数组,两个指针分别指向开头和结尾,找到中间
middle = start + (end - start) / 2;
printf("int型数据大小为 %d 字节\n", sizeof(int));
int intArray[9] = { 0,1,2,3,4,5,6,7,8 };
int* start = intArray;
printf("start指针指向的内容为:%d start指针本身为:%p\n", *start, start);
int* end = intArray + 8;
printf(" end指针指向的内容为:%d end指针本身为:%p\n", *end, end);
int* middle = nullptr;
//!!!!!
middle = start + (end - start) / 2;
//!!!!!
printf("middle指针指向的内容为:%d middle指针本身为:%p\n", *middle, middle);
注意,把指针对应的数值相加再除以2,这样并不正确,原因是这样的
middle = (int*) ( ( (int)start + (int)end ) / 2 );
数据是有长度的,这样可能会指到一个数据的中间去,那当然啥也不是
一个数组,两个指针分别指向开头和结尾,随机找一个
theRandom = start + (rand() % (end - start + 1));
//一个数组,两个指针分别指向开头和结尾,随机找一个
srand(time(NULL));
printf("int型数据大小为 %d 字节\n", sizeof(int));
int intArray[9] = { 0,1,2,3,4,5,6,7,8 };
int* start = intArray;
printf("start指针指向的内容为:%d start指针本身为:%p\n", *start, start);
int* end = intArray + 8;
printf(" end指针指向的内容为:%d end指针本身为:%p\n", *end, end);
int* theRandom = nullptr;
//!!!
theRandom = start + (rand() % (end - start + 1));
//!!!
printf("theRandom指针指向的内容为:%d theRandom指针本身为:%p\n", *theRandom, theRandom);