C Primer Plus Notes 10

1、

从硬件方面来看,被储存的每个值都占用一定的物理内存,C语言把这样的一块内存称为对象(object)。

2、

int entity = 3;

该声明创建了一个名为entity的标识符(identifier)。

3、

int *pt = &entity;

int ranks[10];

第1行声明中,pt是一个标识符,它指定了一个储存地址的对象。但是,表达式*pt不是标识符,因为它不是一个名称。然而,它确实指定了一个对象,在这种情况下,它与entity指定的对象相同。一般而言,那些指定对象的表达式被称为左值。所以,entity既是标识符也是左值;*pt既是表达式也是左值。

4、

作用域:描述程序中可访问标识符的区域。

声明在内层块中的变量,其作用域仅局限于该声明所在的块。

for(int i = 0; i < 10; i++)

printf("A C99 feature: i = %d", i);

上面for循环中的变量i被视为for循环块的一部分,它的作用域仅限于for循环,一旦程序离开for循环,就不能再访问i。

5、

变量的定义在函数的外面,具有文件作用域(file scope)。具有文件作用域的变量,从它的定义处到该定义所在文件的末尾均可见。

#include <stdio.h>

int units = 0;

void critic(void);

int main(void)

{

...

}

void critic(void)

{

...

}

这里,变量 units 具有文件作用域,main( ) 和 critic( ) 函数都可以使用它。由于这样的变量可用于多个函数,所以文件作用域变量也称为全局变量(global variable)。

上面for循环中的变量i被视为for循环块的一部分,它的作用域仅限于for循环。一旦程序离开for循环,就不能再访问i。

6、

C变量有3种链接属性:外部链接、内部链接或无链接。

具有块作用域、函数作用域或函数原型作用域的变量都是无链接变量,这意味着这些变量属于定义它们的块、函数或原型私有。具有文件作用域的变量可以是外部链接或内部链接。外部链接变量可以在多文件程序中使用,内部链接变量只能在一个翻译单元中使用。

默认情况下,文件作用域的变量具有外部链接;使用 static 关键字修饰的文件作用域变量具有内部链接。

7、

C对象有4种存储期:静态存储期、线程存储期、自动存储期、动态分配存储期。

①如果对象具有静态存储期,那么它在程序的执行期间一直存在。文件作用域变量具有静态存储期。

②线程存储期用于并发程序设计,程序执行可被分为多个线程。具有线程存储期的对象,从被声明时到线程结束一直存在。

③块作用域的变量通常都具有自动存储期。当程序进入定义这些变量的块时,为这些变量分配内存;当退出这个块时,释放刚才为变量分配的内存。

块作用域变量也能具有静态存储期。要把变量声明在块中,且在声明前面加上关键字static。

属于自动存储类别的变量具有自动存储期、块作用域且无链接。默认情况下,声明在块或函数头中的任何变量都属于自动存储类别。

8、

静态变量的意思是该变量在内存中原地不动,并不是说它的值不变。

void trystat(void)

{

int fade = 1;

static int stay = 1;

}

第2条声明实际上并不是 trystat( ) 函数的一部分,如果逐步调试该程序会发现,程序似乎跳过了这条声明。这是因为静态变量和外部变量在程序被载入内存时已执行完毕。把这条声明放在 trystat( ) 函数中是为了告诉编译器只有 trystat( ) 函数才能看到该变量。这条声明并未在运行时执行。

9、

int Hocus;

int magic( );

int main(void)

{

int Hocus; // 声明 Hocus ,默认是自动变量

...

}

int Pocus;

int magic( )

{

auto int Hocus; // 把局部变量 Hocus 显式声明为自动变量

...

}

上述例子中,创建了4个独立的变量。main( ) 中的 Hocus 变量默认是自动变量,属于 main( ) 私有。magic( )中的 Hocus 变量被显式声明为自动,只有 magic( ) 可用。外部变量 Hocus 对 main( ) 和 magic( ) 均不可见,但是对该文件中未创建局部 Hocus 变量的其他函数可见。最后, Pocus 是外部变量, magic( )可见,但是 main( ) 不可见,因为 Pocus 被声明在 main( )后面。

10、

int tern = 1;

main( )

{

extern int tern;

}

第1次声明为变量预留了存储空间,该声明构成了变量的定义。(定义声明:defining declaration)

第2次声明只告诉编译器使用之前已创建的tern变量,所以这不是定义。(引用式声明: referencing declaration)。

外部变量只能初始化一次,且必须在定义该变量时进行。

11、

auto 说明符表明变量是自动存储期,只能用于块作用域的变量声明中。

register 说明符也只用于块作用域的变量,它把变量归为寄存器存储类别,请求最快速访问该变量。同时,还保护了该变量的地址不被获取。

static 说明符创建的对象具有静态存储期,载入程序时创建对象,当程序结束时对象消失。如果 static 用于文件作用域声明,作用域受限于该文件。如果 static 用于块作用域声明,作用域则受限于该块。因此,只要程序在运行对象就存在并保留其值,但是只有在执行块内的代码时,才能通过标识符访问。块作用域的静态变量无链接。文件作用域的静态变量具有内部链接。

extern 说明符表明声明的变量定义在别处。

12、

malloc( )函数:

接受一个参数(所需内存的字节数),找到合适的空闲内存块,这样的内存是匿名的。但是函数返回动态分配内存块的首字节地址。因此,可以把该地址赋给一个指针变量,并使用指针访问这块内存。因为char表示1字节,malloc( )的返回类型通常被定义为指向char的指针。

可以使用 malloc( )函数创建动态数组:

double *ptd;

int n;

scanf("%d", &n);

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

free(ptd); // 释放 malloc( ) 分配的内存

13、

free( )所用的指针变量可以与malloc( )的指针变量不同,但是两个指针必须储存相同的地址。也不能释放同一块内存两次。

14、

程序把它可用的内存分为3部分:一部分供具有外部链接、内部链接和无链接的静态变量使用;一部分供自动变量使用;一部分供动态内存分配。

静态存储类别所用的内存数量在编译时确定,只要程序还在运行,就可访问储存在该部分的数据。该类别的变量在程序开始执行时被创建,在程序结束时被销毁。

自动存储类别的变量在程序进入变量定义所在块时存在,在程序离开块时消失。这部分的内存通常作为栈来处理,这意味着新创建的变量按顺序加入内存,然后以相反的顺序销毁。

动态分配的内存在调用malloc( )或相关函数时存在,在调用free( )后释放。所以内存块可以在一个函数中创建,在另一个函数中销毁。未使用的内存块分散在已使用的内存块之间,故使用动态内存通常比使用栈内存慢。

15、

const float *pt; 或 float const *pt;

创建了pt指向的值不能被改变,而pt本身的值可以改变(可以指向其他位置)。

float * const pt;

创建的指针pt本身的值不能更改。pt必须指向同一个地址,但是它所指向的值可以改变。

const float * const pt;

表明pt既不能指向别处,他所指向的值也不能改变。

注:const放在*左侧任意位置,限定了指针指向的数据不能改变;const放在*的右侧,限定了指针本身不能改变。

相关推荐
知花实央l6 小时前
【数字逻辑】24小时数字钟实战!74HC161搭24/60进制计数器+Multisim仿真
算法·测试用例·1024程序员节
安当加密6 小时前
基于ASP身份认证网关实现Web系统免代码改造的单点登录方案
java·开发语言·前端
兮山与6 小时前
算法20.0
算法
island13146 小时前
Rust 零成本抽象原理:性能与安全性的编译期融合
开发语言·rust
头发还没掉光光6 小时前
Linux多线程之生产消费模型,日志版线程池
linux·运维·开发语言·数据结构·c++
CV搬运专家6 小时前
Rust 控制流深度解析:安全保证与迭代器哲学
java·开发语言
hans汉斯6 小时前
基于机器学习的商业银行信贷风险评估系统构建与实证研究
大数据·人工智能·爬虫·算法·yolo·机器学习·支持向量机
云边有个稻草人6 小时前
深入解析 Rust 内部可变性模式:安全与灵活的完美平衡
开发语言·安全·rust
张泽腾666 小时前
<FreeRTOS>
java·开发语言