首页 > 技术文章 > 【C和指针】笔记1

panhao 2015-09-07 20:32 原文

数据


  • 基本数据类型
  1. 整型家族:包含字符,短整型,整型和长整型

整型相互之间大小规定如下:

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

short int至少16位,long int至少32位,缺省的int究竟是16位还是32位,通常这个选择的缺省值是这种机器的最为自然(高效)的的位数。

面对可移植性问题,对于char型变量来说,最好是把存储的变量的值限定在signed char 与 unsigned char的交集内,因为机器中的char是signed与unsigned这是不一定的。

 

两个基本概念:

字面值字面值常量(我的理解就是字面意思上的值的大小),相当于以前书中说的常数。字面值可以用个加上后缀进行区分属于哪种字面值。

比如:加上L和l,可以使这个数被解释为long型整数。

字符常量:单引号包围的字符。

 

  2.枚举类型

这是一个很好用的自然语言符号类型,可以在机器中使用自然语言表示一些值,来代表一些东西。

它的值为符号常量,而不是字面值的类型。

 

下面有两个概念很重要:

  • 数据作用域的问题

 变量在程序的某个部分被声明时,它只在程序的一定区域才能被访问。比如函数的局部变量的作用域局限于该函数体内。这个规则意味着两点:(1)其他函数无法通过这些变量的名字访问他们。(2)只有分属不同的作用域,你可以给不同的变量起同一个名字。

编译器可以确认四种作用域:文件作用域,函数作用域,代码块作用域和原型作用域。

  1. 代码块作用域

位于一对花括号之间的所有语句称为一个代码块。任何在代码块的开始位置声明的标识符都具有代码块作用域,他们可以被代码块中的所有语句访问。

图中标示为6,7,9,10的变量具有代码块作用域。有一种情况,如果内层的标识符名字与外层的标识符名字相同,比如图中6的f与9的f是不同的变量,内层会屏蔽外层的变量,所以在9处使用的是内层的f。

 

  2. 文件作用域

任何在所有代码块之外声明的标识符都具有文件作用域,它表示这个标识符从声明之处直到所有源文件结尾处都是可以访问的。

图中 1和2属于这一类,函数和变量。应该指出的是在头文件中编写,并通过#include指令包含到其他文件中的声明,就好像他们直接写在文件中一样。

 

  3. 原型作用域

原型作用域只适合函数原型声明的参数名。

如图中声明的3和8。原型作用域是为了防止函数原型声明时这些参数名与其他部分名字冲突。唯一可能的冲突就是在同一个原型上不止一次的使用同一个名字。

 

  4.函数作用域

它只适用于语句标签,语句标签用于goto语句,作者说希望你永远不要用到这个知识。

 

  • 链接属性

第一次看到这个词,何为链接属性,我们来看看。

标识符的链接属性决定如何处理在不同文件中出现的标识符。标识符的作用域与链接属性有关,但是两个属性并不相同。

链接属性有三种:external(外部),internal(内部),none(无)

属于external链接属性的标识符不论声明几次,位于几个源文件都表示同一个实体。

属于internal链接属性的标识符在同一源文件中的所有声明都指向同一个实体,但位于不同源文件的多个声明分属不同的实体。一句话就是说,这个属性是把变量绑在这个源文件中的。

属于没有链接属性的标识符,总是被当做单独的个体,也就是说他的多个声明被当做独立不同的实体。

 

这里主要提两个重点关键词:extern,static用于声明中修改标识符的链接属性。

static可以使原本为external属性的变为internal属性。这样的好处是让本文件中的变量和函数只是在这个文件中使用,也可以避免和其他文件的命名冲突。

extern为一个标识符指定external链接属性,这样可以在其他文件中访问这个标识符。

 

  • 存储类型

可以存储变量的三个地方:普通内存,运行时的堆栈,硬件寄存器

变量的缺省存储位置取决于他的声明位置。

静态变量:凡是在任何代码块之外的声明的变量总是存储于静态内存,也就是不属于堆栈的内存,对于这类变量你无法为其指定其他的存储类型。静态变量在程序运行之前创建,在程序的整个执行区间都存在。始终保持原值。

自动变量:代码块内部声明的变量的缺省存储类型是自动的,存储于堆栈中的。auto关键词是修饰这个变量的,不过一般不使用。局部变量,程序执行到声明的地方,变量创建,程序离开代码块,变量自行销毁。

 

两个static声明:

前面提到一个链接属性的static,他是用来修改变量的链接属性,把external改为internal

而在代码块内部,对一个自动变量加上static声明后,可以使它的属性从自动变为静态变量。但是修改变量的存储类型,并不修改该变量的作用域。

 

最后

 1 /*a,b,c的存储类型为静态*/
 2 int         a=5;  //全局变量
 3 extern int     b;      //具有external属性的全局变量
 4 static int  c;      //静态
 5 
 6 int func(int e)
 7 {
 8     int             f=15;        //自动变量
 9     register int     b;
10     static int         g=20;
11     extern int         a;         //多余的,这个代码块位于第一行声明的作用域
12     ...
13     {
14         int e;
15         int a;     //同名变量使用局部的
16         extern int h;  //具有external链接属性,存储于静态内存中
17         ...
18     }
19     ...
20     {
21         int x;
22         int e;
23         ...
24     }
25     ...
26 }
27 
28 static int func2()  //具有静态链接属性,可以防止它被源文件之外的任何函数调用
29 {
30     ...
31 }

 

推荐阅读