c 语言使用疑惑小记
第一段程序:关于一级指针与二级指针:
int *p = NULL;
int **p2 = &p;
cout << p <<endl;
cout << p2 <<endl;
p输出是0,而p2的输出为xxxx.
这里需要注意的是 NULL 不代表地址0,或者说在windows中代表0. NULL作为一个宏定义,任何系统均有自己的实现方式。(代表一个不可取值的地方)。二级指针是指向一级指针的地址,与NuLL无关。
分水线
--------------------------------------------------------------------------------------------------------------------
第二段程序:关于堆栈修改值的问题
有这么一种用法:
void do_signal(long eip) {
*(&eip) = sa_handle;
}
这是linux源码中的一段程序,让人很费解,这里做简要解释,拆分。
void test(unsigned long p, unsigned long b);
int main()
{
int a = 100;
int b = 200;
int *p = &a;
int *q = &b;
test((unsigned long)p, (unsigned long)q);
cout<< *p<<endl;
}
void test(unsigned long p, unsigned long q) {
//*(&p) = b;
cout<< "p:" <<p<<endl;
cout<< "b:" <<q<<endl;
p = q;
cout<< *(int *)p <<endl;
cout << p <<endl;
}
这里需要解释的是: 在调用test函数时,p,q分别存放a,b的地址入栈。
在函数中改变了p的内容(及指针p的指向),所以这里输出的 *(int *)p的值为200
而跳出函数时,*(int*)p 的值仍为100.
貌似本段程序并没有作用, 其实不然:
若在调用test函数之前,手动为test函数建立参数栈,那么改变的就的确是函数栈的真实内容,当函数弹出时,
若对栈不加以回收,那么实际改变的值就真实的存在了程序中。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架