C++57个入门知识点_番外1_C++指针偏移在类中的应用及指针偏移原理

这是对C++指针偏移介绍比较好的博文,但是比较分散,我把其进行了整理,原博文地址请见最后,讲的很详细。

C++57个入门知识点_番外1_C++指针偏移在类中的应用及指针偏移原理

1. C++指针偏移原理

在C++中我们可以通过指针方便的访问各种类型数据,但我们都知道指针只是一个头地址,而我们需要遍历的数据通常占有大量的空间,那么指针是如何遍历其中的数据呢?这就涉及到指针偏移的一个问题,下面我们看个例子:

这里使用了十进制显示地址函数ip2decimal(),详情见下面的“C++显示十进制内存地址”。

	int a[4]={1,2,3,4};
	int* p=&a[0];//将数组a的初始地址传给指针p
	cout<<"指针p的地址:"<<ip2decimal(p)<<endl;
	cout<<"a的地址分别为:"<<endl;
	for (int i = 0; i < 4; i++)
	{
		cout<<ip2decimal(&a[i])<<endl;
	}
 
	for (int i = 1; i < 5; i++)
	{
		cout<<"p地址为:"<<ip2decimal(p)<<"\t数值为:"<<*p<<endl;
		p=p+1;  //指针增加一个int的偏移量
	}

结果为:
在这里插入图片描述
通过上述结果我们可以发现,对于一个存储多个数据的int数组,我们可以通过设定个int* p的指针,只需将数组头指针赋给指针p,便可以通过指针p每次增加一个int数据的偏移量准确获取每个int类型数据。这里int数据的偏移量为4,若为其它类型数据则只需偏移该类型的内存大小即可。
我们可以得出结论对于一个指针其遍历数据时,是通过数据与头地址的偏移量来获取的,而不是变量名。

2. C++显示十进制内存地址(不用理解,直接使用)

我们在C++中显示变量地址均为十六进制的,不具有直观性,尤其在分析连续存储的变量内存地址时。下面分享一个可将十六进制地址转为十进制地址显示的代码,需要注意的是,需要在文件头包含stream与string。

#include <iostream>
#include <sstream>
#include <string>
using namespace std;
 
int ip2decimal(void* ip)
{
		stringstream str;
		string ip_str;
		str<<ip;
		str>>ip_str;
        int bit=0;
        int ans=0;
        for(int i=ip_str.size();i>=0;--i)
		{
            if(ip_str[i]>='0'&&ip_str[i]<='9')
			{
                ans+=(ip_str[i]-'0')*pow(16,bit++);
            }else if(ip_str[i]>='A'&&ip_str[i]<='F')
			{
                ans+=(ip_str[i]-'A'+10)*pow(16,bit++);
            }
        }
        return ans;
}

演示:

int main()
{
	int a=100;
	cout<<"a的十六进制地址:"<<&a<<endl;
	cout<<"a的十进制地址:"<<ip2decimal(&a)<<"\n"<<endl;
	double b=12.5;
	cout<<"b的十六进制地址:"<<&b<<endl;
	cout<<"b的十进制地址:"<<ip2decimal(&b)<<"\n"<<endl;
	string str="xiaoming";
	cout<<"str的十六进制地址:"<<&str<<endl;
	cout<<"str的十进制地址:"<<ip2decimal(&str)<<"\n"<<endl;
	int matrix[3]={1,2,3};
	cout<<"matrix[0]的十六进制地址:"<<&matrix[0]<<endl;
	cout<<"matrix[0]的十进制地址:"<<ip2decimal(&matrix[0])<<endl;
	cout<<"matrix[1]的十六进制地址:"<<&matrix[1]<<endl;
	cout<<"matrix[1]的十进制地址:"<<ip2decimal(&matrix[1])<<endl;
	cout<<"matrix[2]的十六进制地址:"<<&matrix[2]<<endl;
	cout<<"matrix[2]的十进制地址:"<<ip2decimal(&matrix[2])<<endl;
	system("pause");
	return 0;
}

结果:
在这里插入图片描述

3. C++指针偏移在类中的应用

我们知道通过指针访问数据时,并不是依据变量名,而是依据变量内存地址与指针的偏移量大小,具体介绍见上面的“C++指针偏移原理”。
现在我们看一个例子,有两个类people与animal:

class people
{
public:
	int  age_p;
	double weight_p;
	double height_p;
};
 
class animal
{
public:
	int  age_a;
	double weight_a;
};
 
people* p1=new people;
animal* a1;
p1->age_p=24;
p1->weight_p=140;
p1->height_p=180;

通过类的定义我们可以发现,两个类的前两个数据均为int与double,即people与animal这两个类前两项成员变量与对象指针p1、a1的地址偏移量是相同的。既然指针访问数据是根据偏移量大小而不是变量名,那么我们可不可以将p1的地址赋值给a1,然后通过a1去访问age_p与weight_p中的数据呢?

不多说直接上代码:

	a1=(animal*)p1;  //将people的对象指针p1强转成animal*并赋值给a1
	cout<<"指针a1地址:"<<ip2decimal(a1)<<endl;
	cout<<"p1->age_p:"<<a1->age_a<<endl;
	cout<<"p1->weight_p:"<<a1->weight_a<<endl;

结果为:
在这里插入图片描述
完全可行,由此可见对于对象指针访问类中成员变量,同样也是根据成员变量与对象指针的偏移量大小,而不是成员变量名。

参考博文:C++指针偏移在类中的应用C++指针偏移原理C++显示十进制内存地址(无需理解,拷贝即用)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

十月旧城

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

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

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

打赏作者

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

抵扣说明:

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

余额充值