再读《C和指针》(笔记3)

来源:互联网 发布:悠百佳怎么样知乎 编辑:程序博客网 时间:2024/05/02 01:45

一.数据:

  1. 整形包括:字符型,短整型,整型,长整型,它们都分为有符号和无符号两种。
    长整型并不一定比短整型大,因为下面这个规定:
    长整型至少应该和整型一样长,而整型至少应该和短整型一样长,因为这个规定,可能就会有奇异的机器上这三个类型一样长。
    尽管char是为了容纳字符型值的,但字符在本质上是一个小整型值

    2.指针:
    变量的值存储于计算机的内存中,每个变量都占据一个特定的位置,每个内存位置都由地址唯一确定并引用。而指针变量则是:这个变量的值是另外一个变量所处内存处的内存地址,所以指针变量也是变量,不过不像其他char,int等类型存储整数,指针变量存储的是地址。

    3.字符串常量
    字符串常量是一串以NUL字节结尾的零个或多个字符,(NUL是ASCII字符集中的’\0’字符的名字,它的字节为全0)字符串通常存储在字符数组中,这也是C没有显示字符串类型的原因。
    在字符串常量的存储形式中,所有的字符和NUL终止符都存储于内存的某个位置。ANSI C声明如果对一个字符串常量进行修改,其效果是未定义的(很多时候就是出现段错误的原因),所以要修改字符串的话,最好把它存储于数组中。
    在程序中使用字符串常量会生产一个“指向字符的常量指针”。当一个字符串常量出现在一个表达式中时,表达式所使用的值就是这些字符所存储的地址,而不是这些字符本身。所以我们可以把字符串常量赋值给一个“指向字符的指针”。
    注意下面这个条语句:

char *message = "hello world!";

这条语句把message声明为一个指向字符的指针,并用常量字符串中的第一个字符的地址对这个指针进行初始化。
不要对这种赋值方式产生误解,它看上去像是赋初始值给表达式*message,事实上是赋值给message本身。上面的声明其实相当于下面:

char *message;message = "hello world!";

4.作用域

编译器可以确认的4种不同类型的作用域—-文件作用域,函数作用域,代码块作用域和原型作用域。
避免在嵌套的代码中出现相同的变量名,因为这会在程序的调试和维护期间引起混淆!

5.链接属性

当组成一个程序的各个源文件分别被编译之后,所有的目标文件以及那些从其他函数库中引用的函数链接在一起,形成可执行程序。而链接属性将决定如何处理在不同文件中出现的标识符。
链接属性有:external(外部),internal(内部),none(无)。
external:属于external链接属性的标识符不论声明多少次,也不论位于几个源文件,它都表示同一个实体。
internal:属于internal链接属性的标识符在同一个源文件内的所有声明中都指向同一个实体,但位于不同源文件的多个声明则分属不同的实体。
none:没有链接属性的标识符总被当做单独的个体。

关键字extern和static用于在声明中修改标识符的链接属性。如果某个声明在正常情况下具有external链接属性,在它前面加上static关键字可以使它的链接属性变为internal,但static只对缺省属性为external的声明具有改变链接属性的效果。
但static具有两种作用:

1:如上所述,改变链接属性。

2:当static用于代码块内部的变量声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量。但是变量的链接属性和作用域不会受影响。
extern关键字的规则复杂一些,作为一个标识符它指定external链接属性,这样就可以在其他任何位置访问这个实体。当extern关键字用于源文件中一个标识符的第一次声明时,它指定该标识符具有external链接属性,但是如果它用于该标识符的第2次或以后的声明时,它并不会改变链接属性。具有external链接属性的实体总是具有静态存储类型。

6.存储类型
有三个地方用于存储变量:普通内存,运行时堆栈,硬件寄存器。

1,凡是在任何代码块之外声明的变量总是存储于静态内存中,也就是不属于堆栈的内存,称之为静态变量。它们在程序运行之前创建,在程序的整个执行期间一直存在。

2,在代码块内部声明的变量的缺省存储类型是自动的,存储于堆栈中,称为自动变量。auto就是用来修饰这种存储类型的,不过很少用,因为代码块中创建的变量缺省情况下就是自动变量。在代码执行到声明自动变量的代码块时,代码才被创建,当程序的执行流离开该代码块时,自动变量便自行销毁。

3,对代码块内部声明的变量加上static关键字,可以使它的存储类型变为静态变量。但要注意,这只修改它的存储类型而不会修改它的作用域。

4,关键字register可以用于自动变量的声明,提示他们应该存储于机器的硬件寄存器而不是内存,这样存储的访问效率很高,但编译器并不一定理睬register关键字,如果有太多的register变量,它只选取前几个实际存储于寄存器中,其余的就按普通自动变量处理。
在有些寄存器中,把指针声明为寄存器变量会提高程序的效率,尤其是那些频繁执行间接访问操作的指针。

5,自动变量和静态变量的初始化存在重要的差别。
如果不显示的为静态变量指定初始值,静态变量将被初始化为0。

自动变量的初始化需要更多的开销,因为程序链接时还无法确定自动变量的存储位置。事实上,函数的局部变量在函数的每次调用中可能占据不同的位置,基于这个理由,自动变量没有缺省的初始值。而显式的初始化将在代码的起始处插入一条隐式的赋值语句。所以,除非对自动变量进行显示的初始化,否则自动变量创建时它们的值总是垃圾。

0 0
原创粉丝点击