《C和指针》笔记(三)

(三)数据

基本数据类型

在C语言中,仅有4种基本数据类型——整型、浮点型、指针和聚合类型(如数组和结构等)。所有其他的类型都是从这4种基本类型的某种组合派生而来。

长整型至少应该和整形一样长,而整型至少应该和短整型一样长。

指针只是地址的另一个名字,指针变量就是一个其值为另外一个内存地址的变量。

C语言提供了字符串常量,它就是一串以NUL字节结尾的零个或多个字符。由于NUL字节是用于终结字符串的,所以在字符串内部不能有NUL字节。

用于修改变量的长度或是否为有符号数的关键字:short long signed unsigned

基本声明

在声明整型变量时,如果声明中已经至少有了一个其他的说明符,关键字int可以省略。

字符常量的类型总是int,不能在数值后面添加unsigned或long后缀。signed关键字一般只用于char类型,因为其他整型类型在缺省情况下都是有符号数,而char是否是signed因编译器而异。

char *message = “Hello world!”;
这条语句把message声明为一个指向字符的指针,并用字符串常量中第一个字符的地址对该指针进行初始化。
相当于:
char *message;
message = “Hello world!”;

typedef

C语言支持一种叫作typedef的机制,它允许你为各种数据类型定义新名字。

typedef char *ptr_to_char;
这个声明把标识符ptr_to_char作为指向字符的指针类型的新名字,如:
ptr_to_char a;
声明a是一个指向字符的指针。

使用typedef而不是#define来创建新的类型名,因为后者无法正确地处理指针类型,在定义更为复杂的类型名字时,如函数指针或指向数组的指针,使用typedef更为合适。

常量

常量的样子和变量完全一样,只是它们的值不能修改。
int const a;
const int a;
这两条语句都把a声明为一个整数,它的值不能被修改。

常量无法被修改,有两种方法能让它在一开始拥有一个值:
在声明时进行初始化: const int a = 15;
在函数中声明为const的形参在函数被调用时会得到实参的值。

#define指令是另一种创建名字常量的机制。如:
#define MAX_ELEMENTS 50
int const max_elements = 50;
在这种情况下,使用#define比使用const更好,因为只要允许使用字面值常量的地方都可以使用前者,比如声明数组的长度。const变量只能用于允许使用变量的地方。

作用域

只要分属不同的作用域,你可以给不同的变量起同一个名字。

在头文件中编写并通过#include指令包含到其他文件中的声明就好像它们是直接写在那些文件中一样,它们的作用域并不局限于头文件的文件尾。

链接属性

当组成一个程序的各个源文件分别被编译之后,所有的目标文件以及那些从一个或多个函数库中引用的函数链接在一起,形成可执行程序。当相同的标识符出现在几个不同的源文件中时,标识符的链接属性决定如何处理在不同文件中出现的标识符。

链接属性一共有3种,external(外部)、internal(内部)、none(无)。
没有链接属性的标识符(none)总是被当作单独的个体,也就是说该标识符的多个声明被当作独立不同的实体。
属于internal链接属性的标识符在同一个源文件内的所有声明中都指同一个实体,但位于不同源文件的多个声明则分属不同的实体。
属于external链接属性的标识符不论声明多少次、位于几个源文件都表示同一个实体。

typedef char *a;
int b;
int c (int d)
{
    int e;
    int f (int g);
}

在缺省情况下,标识符b、c和f的链接属性为external,其余标识符的链接属性则为none。
如果另一个源文件也包含了标识符b的类似声明并调用函数c,它们实际上访问的是这个源文件所定义的实体。f的链接属性之所以为external是因为它是个函数名,在这个源文件中调用函数f,它实际上将链接到其他源文件所定义的函数,甚至这个函数的定义可能出现在某个函数库。

static:如果某个声明在正常情况下具有external链接属性,在它前面加上static关键字可以使它的链接属性变为internal。
例如 static int b;那么变量b就将为这个源文件所私有。

static只对缺省链接属性为external的声明才有改变链接属性的效果。

extern:一般而言,它为一个标识符指定external链接属性,这样就可以访问在其它任何位置定义的这个实体。 例如为k指定external链接属性,这样函数就可以访问在其他源文件声明的外部变量了。
当extern关键字用于源文件中一个标识符的第1次声明时,它指定该标识符具有external链接属性。但是如果它用于该标识符的第2次或以后的声明时,它并不会更改由第1次声明所指定的链接属性。例如第2次声明并不修改由声明1所指定的变量i的链接属性。

static int i;  
int func()  
{  
    int j;
    extern int k;
    extern int i;
    ...
}

存储类型

变量的存储类型是指存储变量值的内存类型。变量的存储类型决定变量何时创建、何时销毁以及它的值将保持多久。有三个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。

凡是在任何代码块之外声明的变量总是存储于静态内存中,也就是不属于堆栈的内存,这类变量称为静态变量。对于这类变量无法为它们指定其他存储类型。静态变量在程序运行之前创建,在程序的整个执行期间始终存在,它始终保持原先的值,除非给它赋一个不同的值或者程序结束。

在代码块内部声明的变量的缺省存储类型是自动的,也就是说它存储于堆栈中,称为自动(auto)变量。

对于在代码块内部声明的变量,如果给它加上关键字static,可以使它的存储类型从自动变为静态。

关键字register可以用于自动变量的声明,提示它们应该存储于机器的硬件寄存器而不是内存中,这类变量称为寄存器变量。通常,寄存器变量比存储于内存的变量访问起来效率更高。但是,编译器并不一定要理睬register关键字,如果有太多的变量被声明为register,它只选取前几个实际存储于寄存器中,其余的就按普通自动变量处理。

static关键字

当它用于函数定义时,或用于代码块之外的变量声明时,static关键字用于修改标识符的链接属性,从external改为internal,但标识符的存储类型和作用域不受影响。用这种方式声明的函数或变量只能在声明它们的源文件中访问。

当它用于代码块内部的变量声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。用这种方式声明的变量在程序执行之前创建,并在程序的整个执行期间一直存在,而不是每次在代码块开始执行时创建,在代码块执行完毕后销毁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值