C语言内存四大区域几点总结

来源:互联网 发布:计算机数据单位 编辑:程序博客网 时间:2024/05/24 04:08

这里写图片描述

未初始化全局变量默认值为0,未初始化局部变量一般默认值为随机数,但有的编译器也为0。

一、栈:

  栈遵循后进先出,栈的大小由编译器决定。

  • 一般来说,默认栈的大小为1M,所以如果变量分配内存过大可能会造成栈溢出。比如: 定义一个数组长度为200M,double a[1024*1024*200]如果编译器栈大小不够的话会造成溢出。

  • 栈不同于堆,栈用完立即回收,所有局部变量都存放在栈中。
    如下程序会一直进行分配与回收,该程序运行起来会很消耗CPU

while(1){    double  arr[1024*200];}

计算机中计算是由CPU来完成的,而计算结果保存在内存中,所以a+1=2 这种赋值方式是错误的。


二、堆区:

内存分配函数有:malloc calloc realloc
分配的内存不会自动释放,需要配合free()使用。如果执行内存分配以后不释放,则会造成内存泄漏,严重的话会把内存分配完导致计算机崩溃。

用指针写for循环:

 #include <stdio.h> #include <stdlib.h> void main() {     int *p = (int *) malloc(sizeof(int)*10);     int num=0;     int *px=p;       for(;px<p+10;px++)     {         *px=num;         printf("%p\n,%d\n",px,*px);         num++;     }}

注意:

指针本身是一个变量,他存放在栈区(&p)
指针所指向的地址存放在堆区(p)


三、代码段:

  存放函数的执行代码。例如:函数名(函数的入口地址),以及函数的参数。

常量位于代码区,代码区都是只读的。

1、函数指针的定义:

把函数名挖掉,用 (*p) 代替。

例如:void (*pfuc) ( 参数) =fuc; (fuc为函数名)
间接调用: pfuc(参数);

以上两个式子等价于:直接调用fuc(参数)

2、关于const

#define N 10 宏定义有CPU产生,N不可取地址

const修饰的数据是一个伪常量(只读常量),只是限定编译器尽量不修改它修饰的变量,其实是可以间接修改的。

- const在前面   const int nValue;   //nValue是const   const char *pContent; //*pContent是const, pContent可变   const char* const pContent;  //pContent和*pContent都是constconst在后面,与上面的声明对等    int const nValue; //nValue是const    char const * pContent; //*pContent是const, pContent可变    char* const pContent; //pContent是const,*pContent可变    char const* const pContent; //pContent和*pContent都是const
const int num=10;int data[10];      //不合法的,因为num是个伪常量(只读常量)

解析:常量是被编译器放在内存中的只读区域,当然也就不能够去修改它。而”只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量n被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时长度必须是”常量”,”只读变量”也是不可以的,”常量”不等于”不可变的变量”。但是在C++中,局部数组是可以使用变量作为其长度的。

间接修改const修饰数据的值:
所以可以用一个指针指向num,然后就可以通过指针来修改num的值了。

 #include <stdio.h> int main() {     const int num=10;     int *p=(int *)&num;     *p=100;     printf("%d",num); }

四、关于静态变量,局部变量,全局变量,外部变量:

  • 对于局部变量:未初始化也叫定义,所以不能对一个变量申明两次。
  • 对于全局变量:定义=申明+赋值。所以如果没有初始化只能叫做申明,所以可多次申明同一个变量,虽然没有什么意义。
  • 静态变量和局部变量的区别:静态变量被限定在本C文件中才可以使用。

  • 全局变量和外部变量,如下:

 //test1.c int a=2; //test2.c #include <stdio.h>  //int a;      函数体外部只需要申明即可以,但是不能给a赋值,否则就是重定义  void main()  {      extern int a;   //在函数体内部调用其他文件的全局变量,需要用extern申明      printf("%d",a);  }  

这里写图片描述

参数入栈顺序:从左往右
这里写图片描述