存储类、链接和内存管理复习

来源:互联网 发布:java删除文件夹及文件 编辑:程序博客网 时间:2024/05/23 17:00

1。存储类:C为变量提供了5种不同的存储模型,称存储类。存储时期就是变量在内存中保留的时间,

        1)作用域:描述了程序中可以访问一个标识符的一个或多个区域。(代码块作用域、函数原型作用域、文件作用域)

                               函数的形式参量尽管在函数的开始花括号前进行定义,同样也具有代码块作用域,隶属于包含函数体的代码块。

                               函数原型作用域适用于函数原型中使用的变量名。其作用域从变量处一直到原型声明的末尾。

                               一个在所有函数之外定义的变量具有文件域(file scope)。其作用域从它定义处到包含该定义的文件结尾处。文 件作用域也被称作全局变量(globla variable)。

         2)链接:C变量具有下列链接之一:外部链接,内部链接,空链接。

                            具有代码块作用域或者函数原型作用域的变量有空链接。

                            具有文件作用域的变量可能有内部或外部链接。有 static 则内部链接,否则外部链接。

                            一个具有在外部链接的变量可以在一个多文件程序的任何地方使用。一个具有内部链接的变量可以在一个文件的任何地方使用。

          3)存储时期:C变量具有下列两种存储时期之一:静态存储时期和自动存储时期。

                                     如果一个变量具有静态存储时期,它在程序执行期间一直存在。具有文件作用域的变量具有静态存储时期。所有的文件作用域变量,无论它具有何种链接,都具有静态存储时期。

                                     具有代码块作用域的变量一般具有自动存储时期。程序进入定义这些变量的代码块时,分配内存,退出释放。

5种存储类  存储类          时  期         作用域       链    接 声明方式                                 自动         自 动 代码块 空 代码块内 寄存器         自 动 代码块 空 代码块内,使用register 具有外部链接的静态         静 态 文件 外部 所有函数之外 具有内部链接的静态         静 态 文件 内部 所有函数之外,使用static 空链接的静态         静 态 代码块 空 代码块内,使用static

           4)自动变量:属于自动存储类的变量具有自动存储时期、代码块作用域和空链接。默认,在代码块或函数的头部定义的任意变量都属于自动存储类。

                                     如果在内层代码块定义了一个具有和外层代码块变量统一名字的变量,那么内层代码块定义的名字是内层代码所使用的变量。称之为内层定义覆盖了外部定义,但当运行离开内层代码块时,外部变量重新恢复作用。

                                     自动变量须初始化,否则它不会被自动初始化。

            5)寄存器变量:存储类说明符register。寄存器变量多存放在一个寄存器而非内存中,所以无法获得变量地址。

                                           可以把一个形式参量请求为寄存器变量。

            6)具有代码块作用域的静态变量:“静态”是指变量的位置固定不动。具有文件作用域的变量自动具有静态存储时期。

                                                                             可以创建具有代码块作用域,兼具静态存储的局部变量。这些变量和自动变量具有相同的作用域,但当包含这些变量的函数完成工作时,他们不消失。在函数调用期间,计算机都记录着他们的值。static在代码块内声明。

                                                                              静态变量如果不显式的初始化,将被初始化为0。

                                                                              对函数参量不能使用static。

               7)具有外部链接的静态变量:具有外部链接的静态变量具有文件作用于、外部链接和静态存储时期(外部存储类)。这一类型的变量被称为外部变量。把变量的定义声明放在所有函数之外,即创建了一个外部变量。

                                                                      可以在使用外部变了的函数中通过使用extern关键字再次声明。如果变量是在别的文件中定义的,就必须使用extern来声明该变量。

                                                                      在程序执行代码块内语句时,代码块作用域的变量覆盖了具有文件作用域的同名变量。

                                                                      文件作用于变量只可以用常量表达式来初始化。

                8)定义和声明:定义声明,为变量流出了存储空间。构成了变量的定义。称定义声明。

                                              声明只是告诉编译器要使用先前定义的变量,并没有分配空间。因此不是一个定义。称引用声明。

                                              不要用extern来进行外部定义,只用它来引用一个已经存在的外部定义。

                                              外部变量只可以进行一次初始化,而且一定是在变量被定义时进行。

2。分配内存:malloc()和free()

                          malloc()分配内存,但没有指定名字,可以返回第一个字节的地址,可以把这个地址赋给一个指针变量,并且使用这个指针变量来访问那块内存。指向void的指针。(通用指针)。如果malloc()找不到所需空间,返回空指针。

                          例:double *ptd;

                                   ptd=(double *)malloc(30*sizeof(double));

                                   这段代码请求30个double类型值的空间,并且把ptd指向该空间所在位置。注意ptd是作为指向一个double类型值的指针声明的。不是指向30个double类型值的数据块的指针。可以使用ptd[0]来访问内存块的第一个元素。以此类推。

                           一般的,对应每个malloc()调用,应该调用一次free()。函数free()的参数是先前malloc()返回的地址。它释放先前分配的内存。不能使用free()来释放通过其他方式(例如声明一个数组)分配的内存。

                           可以利用此函数创建一个动态数组,即在一个程序运行时才分配内存并可在程序运行时选择大小的数组。使用动态数组将获得程序的灵活性。

                           自动变量使用的内存数量在程序执行时自动增加或者减少。但是被分配的内存所使用的内存数量只会增加。除非使用free()。如果不使用free(),可能会造成内存泄露(memory leak)。

                           内存分配还可以使用calloc()。特性:它将块中的全部位都置为0。

                           例:long *newmem;

                                   newmem=(long *)calloc(100,sizeof(long));

                           第一个参数是所需内存单元的数量,第二个参数是每个单元以字节计的大小。

3。ANSI C的类型限定词const、volatile、restric

             1)如果变量声明中带有关键字const,则不能通过赋值、增量或减量运算来修改该变量的值。

                   在指针和参量声明中使用const。

                   const  float  *pf   等同于  float  const  *pf    //pf指向一个常量浮点数值。pf指向的值不能改变。但pf本身的值可以改变。

                   const  *float  pt                    //pt是一个常量指针。它必须总是指向同一个地址,但所指的值可以改变。

                   const  float *const ptr        //ptr总是必须指向同一位置,并且指向的值也不能改变。

                   总之,一个位于*左边任意位置的const使得数据成为常量,而一个位于*右边的const使得指针自身成为常量。

               2)关键字restrict只可用于指针,并且表明指针是访问一个数据对象的唯一且初始的方式。

               3)限定词volatile告诉编译器该变量除了可被程序改变以外还可被其他代理改变。典型的,被用于硬件地址与其他并行运行的程序共享的数据。

                      一个值可同时是const和volatile。例如硬件时钟一般设定为不能由程序改变,这一点它成为const,但它被程序以外的代理改变,这使他成为volatile。只需在声明中同时使用这两个限定词。顺序并不重要。

原创粉丝点击