C和指针 学习笔记—第3章

第三章 数据

 

1、变量的三个属性:作用域、链接属性和存储类型(这三个属性决定了一个变量的“可视性”(也就是它可以在什么地方使用)和“生命期”(它的值将保持多久))。

2、char类型变量的目的是为了让它们容纳字符型值,但字符在本质上是最小整型值;缺省的char要么是signed char,要么是unsigned char,这取决于编译器。只有当char型变量显式声明为signed或unsigned时,才对它执行算术运算。

3、枚举类型就是指它的值为符号常量而不是字面值的类型。对于枚举类型,如果某个符号名未显式指定一个值,默认基础类型为int,默认情况下,第一个枚举元素的值为0,后面每个枚举元素依次加1。

4、字符串通常存储在字符数组中,这也是C语言么有显式的字符串类型的原因。如果需要修改字符串,请把它存储于数组中

由于程序中使用字符串常量会生成一个“指向字符的常量指针”,所以当一个字符串常量出现于一个表达式中时,表达式所使用的

值就是这些字符所存储的地址,而不是这些字符本。因此,你可以把字符串常量赋值给一个“指向字符的指针”,后者指向这些

字符所存储的地址。但是,你不能把字符串常量赋值给一个字符数组,因为字符串常量的直接值是一个指针,而不是这些字符身。

例如:char *message = “Hello World !”;

字符串常量Hello World!相当于一个地址,所以赋值给一个指针变量是可以的

5、typedef类型,它允许为各种数据类型定义新名字。

typedef与宏定义的区别?

宏定义用来替代变量或者函数,放在程序的头部,在编译时进行变量替代,在预处理完成,它本身并不占用编译内存。而typedef在

编译时处理的,而不是简单的替换,是对类型说明符重新命名。

6、编译器可以确认4种不同类型的作用域——文件作用域、函数作用域、代码块作用域和原型作用域。

代码作用域:

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

个代码块中的所有语句访问。

当代码块处于嵌套状态时,声明与内层代码块的标识符的作用域到达该代码块的尾部便告终止。然后内层代码块有一个标识符的名

字与外层代码块的一个标识符同名,那么内层的那个标识符就将隐藏外层的标识符——外层的那个标识符无法在内层代码块中通过

名字访问。

在K&R C中,函数形参的作用域开始于形参的声明处,位于函数体之外。

文件作用域:

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

原型作用域:

原型作用域适用于在函数原型中声明的参数名。

函数作用域:

函数作用域只适用于语句标签,语句标签用于goto语句

7、当组成一个程序的各个源文件分别被编译之后,所有的目标文件以及那些从一个或多个函数库中引用的函数链接在一起,形成可执行程序。

链接属性有3中——external(外部)、internal(内部)和none(无)没有链接属性的标识符(none)总是被当做单独的个体,

也就是说该标识符的多个声明被当做独立不同的实体属于internal链接属性的标识符在同一个源文件内的所有声明中都指向同一

个实体,但位于不同源文件的多个声明则分属不同实体。最后,属于external链接属性的标识符不论声明多少次,位于几个源文件

都表示同一个实体。

8、存储类型

变量的存储类型是指存储变量值的内存类型;变量的存储类型决定变量何时创建、何时销毁、以及它的值能保持多久。

有3个地方可以存储变量:普通内存、运行时堆栈、硬件寄存器

变量的缺省存储类型取决于它的声明位置:

(1)凡是在任何代码块之外声明的变量总是存储于静态内存中,这类变量称为静态变量,静态变量在程序运行之前创建,在程序的整个执行期间始终存在

(2)在代码块内部声明的变量的缺省存储类型是自动的,也就是说它存储于堆栈中,称为自动变量;在程序执行到声明自动变量的代码块时,自动变量才被创建,当程序的执行流离开该代码块时,这些自动变量便自行销毁。如果你反复调用这些代码块,这些变量就会反复创建和销毁,他们存储的位置可能与上一次存储的位置相同,可能不同。

(3)在代码块内部声明的变量,如果给它加上关键字static,可以使它的存储类型从自动变为静态,但是修改变量的存储类型并不表示修改该变量的作用域。

(4)关键字register可以用于自动变量的声明,提示他们应该存储于机器的硬件寄存器而不是内存中,这类变量称为寄存器变量。通常寄存器变量效率要比存储于内存中的变量的访问效率高,但是编译器不一定将所有的register声明的变量存储于寄存器,可能只是选取前几个,其余按自动变量处理。

一旦一个变量称为寄存器变量,机器并不像你提供寄存器变量的地址!!

(由于寄存器值得保存和恢复,某个特定的寄存器在不同的时刻所保存的值不一定相同)

初始化:

静态变量如果不显式的指定其初始值,静态变量将初始化为0;

自动变量在链接时,链接器无法判断自动变量的存储位置,因为函数的局部变量在函数的每调用都可能占据不同的位置,基于这个理由,自动变量没有缺省值;

因此上面原因有四个影响:

首先,是自动变量的初始化相比赋值语句效率并无提高;

其次,每次调用都会重新初始化;

再次,你可以使用任何表达式作为初始化值;

第四,如果自动变量不初始化,它的值时不确定的

9、编译器并不检查对数组下标的引用是否符合数组的合法范围内,一个良好的经验法则是:

如果下标值时从那些已知是正确的值计算而来的,那么无需检查它的值,如果一个用作下标的值时根据某种方法从用户输入的数据产生而来的,那么在使用它之前必须进行检测,确保他们位于有效的范围之内。

10、局部变量由函数内部使用,不能被其他函数通过名字引用,它在缺省的情况下的存储类型为自动,这是基于两个原因:

(1)当这些变量需要时才为它们分配存储,这样可以减少内存的总需求量

(2)在堆栈上为它们分配存储可以有效地实现递归

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值