(给Linux爱好者加星标,提升Linux技能)
转自:拓跋阿秀
1、在main执行之前和之后执行的代码可能是什么?main函数执行之前,主要就是初始化系统相关资源:
设置栈指针
初始化静态static变量和global全局变量,即.data段的内容
将未初始化部分的全局变量赋初值:数值型short,int,long等为0,bool为FALSE,指针为NULL等等,即.bss段的内容
全局对象初始化,在main之前调用构造函数,这是可能会执行前的一些代码
将main函数的参数argc,argv等传递给main函数,然后才真正运行main函数
main函数执行之后:
全局对象的析构函数会在main函数之后执行;
可以用atxit注册一个函数,它会在main之后执行;
2、结构体内存对齐问题?结构体内成员按照声明顺序存储,第一个成员地址和整个结构体地址相同。
未特殊说明时,按结构体中siz最大的成员对齐(若有doubl成员,按8字节对齐。)
3、指针和引用的区别指针是一个变量,存储的是一个地址,引用跟原来的变量实质上是同一个东西,是原变量的别名
指针可以有多级,引用只有一级
指针可以为空,引用不能为NULL且在定义时必须初始化
指针在初始化后可以改变指向,而引用在初始化之后不可再改变
sizof指针得到的是本指针的大小,sizof引用得到的是引用所指向变量的大小
当把指针作为参数进行传递时,也是将实参的一个拷贝传递给形参,两者指向的地址相同,但不是同一个变量,在函数中改变这个变量的指向不影响实参,而引用却可以。
引用只是别名,不占用具体存储空间,只有声明没有定义;指针是具体变量,需要占用存储空间。
引用在声明时必须初始化为另一变量,一旦出现必须为typnamrfnamvarnam形式;指针声明和定义可以分开,可以先只声明指针变量而不初始化,等用到时再指向具体变量。
引用一旦初始化之后就不可以再改变(变量可以被引用为多次,但引用只能作为一个变量引用);指针变量可以重新指向别的变量。
不存在指向空值的引用,必须有具体实体;但是存在指向空值的指针。
参考代码:
voidtst(int*p){
inta=1;
p=a;
coutp""*pndl;}intmain(void){int*p=NULL;tst(p);if(p==NULL)cout"指针p为NULL"ndl;rturn0;}//运行结果为://0x22ff//指针p为NULLvoidtstPTR(int*p){inta=12;p=a;}voidtstREFF(intp){inta=12;p=a;}voidmain(){inta=10;int*b=a;tstPTR(b);//改变指针指向,但是没改变指针的所指的内容coutandl;//10cout*bndl;//10a=10;tstREFF(a);coutandl;//12}4、堆和栈的区别
申请方式不同:栈由系统自动分配;堆是自己申请和释放的。
申请大小限制不同:栈顶和栈底是之前预设好的,栈是向栈底扩展,大小固定,可以通过ulimit-a查看,由ulimit-s修改;堆向高地址扩展,是不连续的内存区域,大小可以灵活调整。
申请效率不同:栈由系统分配,速度快,不会有碎片;堆由程序员分配,速度慢,且会有碎片。
形象的比喻
栈就像我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
《C++中堆(hap)和栈(stack)的区别》: