像机器一样思考之c/c++语言(1)

本文探讨了C/C++中的内存管理,包括堆栈的生长方向,通过测试代码展示了内存从高地址向低地址增长的特性。同时,讲解了大端和小端模式的概念,并通过实例验证了系统采用的是小端模式。此外,还分析了STL堆栈(STACK)的增长方式,发现其与堆类似,由低地址向高地址扩展。最后提出一个问题,如何在不传递参数的情况下,从print函数内部访问并打印main函数中数组arr的元素,并给出了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆栈

Segment 1 内存增长方式

测试代码:

#include<iostream>
using namespace std;
int main()
{
int a=3;
int b=4;
int c=5;
cout<<&a<<endl;
cout<<&b<<endl;
cout<<&c<<endl;
return 0;
}

过程显示:

地址大小:a>b>c。说明数据存储的内存增长方式是从大到小,这和“栈”向低地址“生长”的方式相同,堆则相反。



Segment 2 大小端

 大端模式,是指数据的高位,保存在内存的低地址中,而数据的低位,保存在内存的高地址中;小端模式,是指数据的高位保存在内存的高地址中,而数据的低位保存在内存的低地址中。

测试代码:

#include<iostream>
using namespace std;
int main()
{
int number = 1;
if(*(char *)&number) cout<<"Little-endian!\n";
else
cout<<"Big-endian!\n";
return 0;
}

结果:Little-endian!


Segment 3 STL中堆栈STACK的增长方式

测试代码:

#include<iostream>
#include<stack>
using namespace std;
int main()
{
stack<int> sOne;
int iArry[]={3,4,5,2,1};
for(int i=0;i<sizeof(iArry)/sizeof(int);i++)
sOne.push(iArry[i]);
while(!sOne.empty())
{int *p=&sOne.top();//p指向栈顶
cout<<p<<" is "<<*p<<endl;
sOne.pop();
}
return 0;
}

输出结果:


结果表明堆栈的生长方式是由低地址向高地址,表现和堆的增长方式一样。看到这个结果表示很惊讶。




问题:(具体问题和解答见《c语言进阶 重点、难点与疑点解析page3-5》)

要求不在传递参数的情况下,在print函数中打印出main()函数中arr数组中的各个元素。

#include<iostream>
using namespace std;

void print(){
//填充代码
}
int main()
{int a=1;int b=2;
char c='a';
int arr[]={11,12,13,14,15,16,17};
print();
return 0;
}

解决方法:

void print(){
unsigned int _ebp;
_asm{
mov _ebp,ebp;
}
int *p=(int *)(*(int *)_ebp-4-4-4-7*4);
for(int i=0;i<7;i++)
cout<<p[i]<<endl;
}

把以上代码添加到print()函数,在vc++6.0上成功实现。但在vs2008中要把int *p=(int *)(*(int *)_ebp-4-4-4-7*4)改为int *p=(int *)(*(int *)_ebp-4-4-4-7*4-7*4)。希望高手解答。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值