黑马程序员--C语言指针与动态内存分配

来源:互联网 发布:软件需求调查问卷 编辑:程序博客网 时间:2024/04/29 18:12

----------------------ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------



一、存储划分

  1、在C语言中,存储区大致分为5类:栈、堆、静态区、常量区、代码区。

  2、栈

      1)由编译器自动分配和释放

      2)在函数体中定义的变量通常在栈上

      3)栈中的变量先进后出

      4)栈中的变量一般出了函数会被释放

3、堆

      1)一般由程序员分配和释放,若程序员不释放,程序结束时由OS释放

      2)用malloc、calloc、realloc等分配内存的函数分配得到的就在堆上

      3)释放堆内存free()

  4、全局区(静态区)

      1)全局变量和静态变量的存储是放在一块的

      2)初始化的全局变量和静态变量在一块区域

      3)未初始化的全局变量和未初化的静态变量在相邻的另一块区域

      4)程序结束释放


5、常量区

      1)专门存放常量的地方

      2)例如13,'a',-3.8,"fhkad"

      3)程序结束释放

6、代码区

      1)存放二进制代码的区域

      2)函数通常会被编译成二进制代码,存储在代码区

      3)函数被调用的时候,会从代码区取出,函数需要的参数以及函数体中的变量,会在栈里临时分配,函数结束时,变量会被释放

二、指针赋值

      1、C语言允许使用赋值运算符进行指针的复制,前提是两个指针具有相同的类型

     

三、指针做为参数

   1、指针作为参数的作用

   2、定义一个交换两个整形变量的值的函数。如果定义成以下形式:

      void swap(int num_1,int num_2);

     

3、函数传参的过程:把实际参数的值拷贝到形式参数:

void swap_sec(int*num_1,int *num_2)


四、指针作为返回值

  1、我们不仅可以为函数传递指针,还可以编写返回指针的函数

  2、函数可以返回指向外部变量或指向声明为static的局部变量的指针

  3、注意:

     永远不要返回指向自动局部变量的指针。函数结束后,局部变量就不存在了,所以指向局部变量的指针是无效的

五、动态内存分配:

1、malloc()函数  在运行时分配内存的最简单的标准库函数是malloc()。使用这个函数时,需要在程序中包含头文件。使用malloc()函数需指定要分配的内存字节数作为参数。这个函数返回所分配内存的第一个字节的地址。因为返回的是一个地址,所以这里可以使用指针。 

动态内存分配的一个例子如下: 

int *pNumber = (int *)malloc(100); 

这条语句请求100个字节的内存,并把这个内存块的地址赋予pNumber。只要不修改它,任何时间使用这个变量pNumber,它都会指向所分配的100个字节的第一个int的位置。这个内存块能保存25个int值,每个int占4个字节。 

注意,类型转换(int*)将函数返回的地址转换成int类型的指针。这么做是因为malloc()是一般用途的函数,可为任何类型的数据分配内存。这个函数不知道要这个内存作什么用,所以它返回的是一个void类型的指针,写做void*。类型void*的指针可以指向任意类型的数据,然而不能取消对void指针的引用,因为它指向未具体说明的对象。许多编译器会把malloc()返回的地址自动转换成适当的类型,且不会伤害具体指定的对象。 

可以请求任意数量的字节,字节数仅受制于计算机中未用的内存以及malloc()的运用场合。如果因某种原因而不能分配请求的内存,malloc()会返回一个NULL指针。这个指针等于0。最好先用if语句检查请求动态分配的内存是否已分配,再使用它。就如同金钱,没钱又想花费,会带来灾难性的后果。因此,应编写如下语句: 

if(pNumber == NULL) {

/*Code  to  deal with  no  memory  allocated  */

}

如果指针是NULL,最好执行适当的操作。例如,至少可以显示一条信息"内存不足",然后中止程序。这比允许程序继续执行,使之使用NULL地址存储数据导致崩溃要好得多。然而,在某些情况下,可以释放在别的地方使用的内存,以便程序有足够的内存继续执行下去。

2、分配内存时使用sizeof运算符 

前一个例子很不错,但我们不常处理字节,而常常处理int、double等数据类型。例如给75个int类型的数据项分配内存,可以使用以下的语句: 

pNumber = (int *)malloc(75*sizeof(int)); 

如前所述,sizeof是一个运算符,它返回一个size_t类型的无符号整数,该整数是存储它的参数需要的字节数。它把关键字如int或float等作为参数,返回存储该类型的数据项所需的字节数。它的参数也可以是变量或数组名。把数组名作为参数时,sizeof返回存储整个数组所需的字节数。前一个例子请求分配足以存储75个int数据项的内存。以这种方式使用sizeof,可以根据不同的C编译器为int类型的值自动调整所需的内存空间。



----------------------ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------


0 0