怎样优化自己的网站,不花钱可以做网站吗,北京网站建设一站式服务,做物流网站模块以下内容源于C语言中文网的内容学习与整理。如有侵权#xff0c;请告知删除。 一、C语言内存布局 C程序所占用的内存#xff0c;可以划分为以下几个部分。 1、栈区#xff08;stack#xff09;。由编译器自动分配释放#xff0c;存放函数的参数值#xff0c;局部变量的值…以下内容源于C语言中文网的内容学习与整理。如有侵权请告知删除。 一、C语言内存布局 C程序所占用的内存可以划分为以下几个部分。 1、栈区stack。由编译器自动分配释放存放函数的参数值局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区heap。一般由程序员分配释放若程序员不释放程序结束时可能由操作系统回收。注意它与数据结构中的堆是两回事分配方式类似于链表。 其中栈区、堆区又合称“动态存储区”而全局区、文字常量区、程序代码区合称“静态存储区”。动态存储区在程序执行过程中动态分配大小随之动态变化静态存储区的大小在程序编译连接阶段就已经确定。 3、全局区或者叫静态区static。全局变量和静态变量是放在一起存储的初始化的全局变量和静态变量在一块区域全局初始化区未初始化的全局变量和未初始化的静态变量在相邻的另一块区域全局未初始化区。全局区在程序结束后由系统释放。 4、文字常量区。存放一般常量、字符串常量程序结束后由系统释放。 5、程序代码区。存放函数体的二进制代码。 二、实例解释
//main.c
#includestdio.h
#includestring.hint a0; //全局初始化区
char *p1; //全局未初始化区 int main(int argc,char** argv)
{ int b; //栈 char s[]abc;//栈 char *p2; //栈 char *p3123456; //123456/0在常量区p3在栈上 static int c0//全局静态初始化区 p1(char*)malloc(10); //分配得到的10和20字节的区域就在堆区p2(char*)malloc(20);//123456/0放在常量区编译器可能会将它与p3所指向的123456 优化成一个地方 strcpy(p1,123456);
}
三、关于堆与栈的理论知识 1、申请方式 1栈 由系统自动分配。比如在函数中声明一个局部变量“int b;”则系统自动在栈中为b开辟空间。2堆 需要程序员自己申请并指明大小。 在C中使用malloc函数进行申请如“ p1(char*)malloc(10); ”。 在C中用new运算符如“p2 new char[10]; ”。 注意p1、p2本身是在栈中的。 2、申请后系统的响应 1栈 只要栈的剩余空间大于所申请空间系统将为程序提供内存否则将报异常提示栈溢出。 2堆 操作系统有一个记录空闲内存地址的链表当系统收到程序的申请时会遍历该链表寻找第一个空间大于所申请空间的堆结点然后将该结点从空闲结点链表中删除并将该结点的空间分配给程序。大多数系统会在这块内存空间中的首地址处记录本次分配的大小因而代码中的delete语句才能正确地释放本内存空间。另外由于找到的堆结点的大小不一定正好等于申请的大小系统会自动将多余的那部分重新放入空闲链表中。 3、申请大小的限制 1栈 在Windows下栈是向低地址扩展的数据结构是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的。 在WINDOWS下栈的大小是2M也有的说是1M总之是一个编译时就确定的常数如果申请的空间超过栈的剩余空间时将提示overflow。因此能从栈获得的空间较小。 2堆 堆是向高地址扩展的数据结构是不连续的内存区域。这是因为系统使用链表来存储空闲内存地址所以自然是不连续的而链表的遍历方向是由低地址向高地址。 堆的大小受限于计算机系统中有效的虚拟内存。由此可见堆获得的空间比较灵活也比较大。 4、申请效率的比较 1栈 栈由系统自动分配速度较快。但程序员是无法控制的。 2堆 堆是使用malloc相关函数或者由new来分配的内存一般速度比较慢而且容易产生内存碎片不过用起来最方便。 另外在WINDOWS下最好的方式是用VirtualAlloc分配内存它直接在进程的地址空间中保留一块内存虽然用起来最不方便但是速度快也最灵活。 5、堆和栈中的存储内容 1栈 在函数调用时第一个进栈的是函数调用语句的下一条可执行语句的地址然后是函数的各个参数在大多数的C编译器中参数是由右往左入栈的然后是函数中的局部变量。 注意静态变量是不入栈的。 当本次函数调用结束后局部变量先出栈然后是参数最后栈顶指针指向最开始存的地址也就是主函数中的下一条指令程序由该点继续运行。 2堆 一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。 6、存取效率的比较 char s1[] aaaaaaaaaaaaaaa;
char *s2 bbbbbbbbbbbbbbbbb; 上面代码中aaaaaaaaaaa是在运行时刻赋值的而bbbbbbbbbbb是在编译时就确定的。在以后的存取中在栈上的数组比指针所指向的字符串例如堆快。 比如 #includestdio.hint main(int argc,char* argv[])
{ char a1; char c[] 1234567890; char *p 1234567890; a c[1]; a p[1];return;
} 对应的汇编代码 10: a c[1]; 00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh] 0040106A 88 4D FC mov byte ptr [ebp-4],cl 11: a p[1]; 0040106D 8B 55 EC mov edx,dword ptr [ebp-14h] 00401070 8A 42 01 mov al,byte ptr [edx1] 00401073 88 45 FC mov byte ptr [ebp-4],al 第一种在读取时直接就把字符串中的元素读到寄存器cl中而第二种则要先把指针值读到edx中再根据edx读取字符显然慢了。 7、小结 堆和栈的区别可以用如下的比喻来看出 使用栈就像我们去饭馆里吃饭只管点菜发出申请、付钱和吃使用吃饱了就走不必理会切菜、洗菜等准备工作以及和洗碗、刷锅等扫尾工作。它的好处是快捷但是自由度小。 使用堆就像是自己动手做喜欢吃的菜肴比较麻烦但是比较符合自己的口味而且自由度大。