C/C++关于指针

以下是本人对于指针的理解

计算机把地址当作整数来处理,可以简单的认为指针就是整数,这个整数是数据的存储地址

我这里是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);

在这里插入图片描述

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cctv1324

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值