【C/C++】指针步长——例题理解
链接地址:指针步长——例题理解
一、例题
下面程序的执行结果:
class A{
public:
long a;
};
class B : public A {
public:
long b;
};
void seta(A* data, int idx) {
data[idx].a = 2;
}
int main(int argc, char *argv[]) {
B data[4];
for(int i=0; i<4; ++i){
data[i].a = 1;
data[i].b = 1;
seta(data, i);
}
for(int i=0; i<4; ++i){
std::cout << data[i].a << data[i].b;
}
return 0;
}
A,21212121
B,22221111
A和B你会选择哪一个呢?
二、解析
正确答案为B,是不是很疑问呢
首先明确, A类 大小为 4字节;B 类大小为 8字节
因为B继承自A,基类A有一个long,4字节,派生类B继承A的long加上自身定义了一个long,4+4=8个字节。
所以,A类指针+1移动4字节,B类指针+1移动8字节,所以A类指针和B类指针的移动步长不相同
void seta(A* data, int idx) {
data[idx].a = 2;
}
由代码可知,此处传入的实参为B类,而形参却为A类,所以这里就是使用基类A类指针来操作,子类B类的数据。
因为A类和B类指针步长不同的原因,就会出现指针实际操作的目标地址,与想象中的目标地址不相同
下面展示,此例题中,因为指针步长不同的原因,所对应的操作地址
因此每执行一次此函数,就会进行4字节对应地址的数据替换。
seta(data, i);
所以答案就为22221111
因此类推,若将此函数void seta(A* data, int idx);中的A类改为B类,就不会存在指针步长不同的问题,答案就会是21212121
如有不足之处,还望指正 [1]。
如果对您有帮助可以点赞、收藏、关注,将会是我最大的动力 ↩︎