Standard C Episode 5

理解变量标识符的作用域和可见性,以及变量生存期。
(1)标识符的作用域和可见性
    作用域:作用域是一个标识符在源程序中有效的区域。
    可见性:程序运行到某一点,能够引用到的标识符,就是该处可见的标识符。

(2)变量生存期:
    变量的生存期就是指变量从创建到销毁的时间范围。变量按照生存期分“静态生存期”和“动态生存期”。静态生存期:如果变量的生存期与程序的运行期相同,则称该变量具有“静态生存期”; 动态生存期:变量生存期始于创建声明点,结束于作用域结束处。

注意:源程序声明(定义)变量原则:满足需要的情况下,缩短标识符作用域,缩短变量生存期。

 1 /*
 2 *变量练习
 3 *
 4 *理解标识符的作用域和可见性,以及变量生存期。
 5 *
 6 *作用域:作用域是一个标识符在源程序中有效的区域。
 7 *可见性:程序运行到某一点,能够引用到的标识符,就是该处可见的标识符。
 8 *
 9 *
10 *变量生存期:变量的生存期就是指变量从创建到销毁的时间范围。
11 *
12 *变量按照生存期分“静态生存期”和“动态生存期”。
13 *静态生存期:如果变量的生存期与程序的运行期相同,则称该变量具有“静态生存期”;
14 *动态生存期:变量生存期始于创建声明点,结束于作用域结束处。
15 */
16
17 int value;//对于全局变量,编译器会在编译期自动初始化为零
18
19 void func()
20 {
21     int value2 = 2;//局部变量
22     printf("%d\n", value2);
23 }
24
25 int main()
26 {
27 value4 = 0;//局部变量。
28     {
29         int value3 = 3;//局部变量。
30                 //该条变量定义语句定义的变量作用域为:自其定义语句起到当前大括号结束为止。
31                 //我们称这类局部变量具有“块作用域”,也称为“块变量”
32         printf("%d\n", value3);
33         printf("%d\n", value4);
34     }
35 //func();
36 //printf("%d\n", value2);//编译器error:value2没有被定义
37 //printf("%d\n", value3);//编译器error: value3没有被定义。
38 return 0
39 }

变量类型修饰符(type-specifier)
auto关键字可以用来声明变量,所有的局部变量自动就是auto的,所以源程序中根本不需要特别声明。

static关键字可以用来声明静态变量。静态全局变量的作用域被缩小成声明它的那个文件里面的所有语句。静态局部变量在程序一开始运行就被创建直到程序结束才被销毁,它的生存期被拉长为整个程序运行期。
    /*static类型修饰符修饰局部变量时可以实现改变变量的生存期,但无法改标识符在源程序中的作用域和可见性。
     *static类型修饰符修饰全局变量时可以实现改变变量的作用域。*/

register关键字可以用来声明寄存器变量。

volatile关键字可以声明易变变量。

const关键字可以用来声明不可变变量。

语言中的地址数据和指针
指针变量是用来存放地址数据的变量。
指针变量声明语法如下:
int *p_value;//声明语句中标识符前的星号表示p_value是指针类型。
int *p_value1, value1, *p_value2, temp,
integer;//本声明语句中的标识符有星号的表示是指针类型,没有星号的是int类型。也就是说p_value1,
p_value2的类型是int*, value1, temp, integer的类型是int
    
两个最基本的地址运算操作符&和*。其中*是间接访问操作符,&是取址操作符。他们的运算优先级极高。

范例练习:

 1 /*
 2 *秒表练习
 3 *了解库函数sleep()  time()
 4 *
 5 */
 6
 7 #include <stdio.h>
 8 #include <time.h>
 9 #include <unistd.h>
10
11 int main()
12 {
13     int start = time(0);//time(0)返回值是现今与1970年1月1日0时0分0秒(0时区)的秒数
14     while(1) {
15         printf("%d\r", time(0) - start);//注意printf打印输入字符流时候,首先是将输出字符放入输出缓冲区,当输出缓冲区中有换行符时候才会打印到屏幕
16         fflush(stdout);//立即打印输出缓冲区中的字符流
17         sleep(1);//库函数sleep实现让当前程序休眠一秒钟
18     }
19     return 0;
20 }
 1 /*
 2  * const type-specifier练习
 3  *
 4  * */
 5
 6 #include <stdio.h>
 7
 8 int main()
 9 {
10     const int value = 0;
11     printf("value是%d\n", value);
12     //value = 3;//编译报错,const 类型修饰符只能在初始化时候放入数据,一旦初始化完成就不能再放入数据。也就是说变量value不再改变。
13     //value++;
14     printf("value是%d\n", value);
15
16     return 0;
17 }
 1 /*
 2  * 静态局部变量练习
 3  * */
 4
 5 #include <stdio.h>
 6
 7 void f()
 8 {
 9     //int value = 0;
10     static value = 0;//静态局部变量在程序一开始运行时就被创建了,直到整个程序运行结束才会被销毁。静态局部变量具有静态生存期。
11     /*static类型修饰符修饰局部变量时可以实现改变变量的生存期,但无法改标识符在源程序中的作用域和可见性。
12      *static类型修饰符修饰全局变量时可以实现改变变量的作用域。*/
13     printf("f()中value是%d\n", value);
14     value++;
15 }
16
17 int main()
18 {
19     f();
20     f();
21     return 0;
22 }
 1 /*
 2  * 函数返回指针类型数据
 3  *
 4  *
 5  * 指针变量可以作为函数返回值使用,只能把全局变量的地址、静态局部变量的地址或者通过参数获得的地址当做返回值使用。普通局部变量因生存期问题导致使用普通变量的地址作为返回值非常危险,所以绝对不要讲普通局部变量的地址作为返回值使用。
 6  *
 7  * */
 8 #include <stdio.h>
 9 int *func()
10 {
11     static int value = 0;
12     printf("value是%d\n", value);
13
14     return &value;
15 }
16
17 int main()
18 {
19     int *p_value = NULL;
20     p_value = func();
21     printf("p_value = func(); *p_value是%d\n", *p_value);
22     *p_value = 7;
23     func();
24     printf("*p_value是%d\n", *p_value);
25     return 0;
26 }
时间: 2024-10-17 06:54:01

Standard C Episode 5的相关文章

Standard C episode 1

计算机内存可以记录大量的信息,只有记录在内存中的信息才是可以使用的.计算机的内存管理者是操作系统.程序可以根据需要向操作系统申请存储区,所有存储区必须先申请并经过操作系统分配后才能由程序使用.我们知道计算机里的信息可以简单划分为: /指令       /控制信息 信息 -            \控制字       \数据信息                     |              /              \      数值信息     非数值信息       /    \ 

Standard C Episode 3

程序语言中的控制流语句用于控制各计算操作执行的次序.控制流结构有:(1)顺序结构(2)分支结构(3)循环结构 if...else语句是经典的分支结构控制语句,同样"switch (表达式)...case 常量表达式" 语句也可以实现分支处理."表达式"可以是任何表达式,"常量表达式"也可以是任何常量表达式.case分支一般包含多条语句时也不必用大括号括起来,因 为每一个case分支只会给出switch分支结构中语句执行的开始位置,而不确定终止位置

Standard C Episode 2

源程序中,但凡可以出现某种类型的数据的地方都可以用同类型的表达式替换.一个表达式的类型,取决于多个方面. 操作符有单目操作符和双目操作符, 还有三目操作符(? : 是C语言唯一的一个三目操作符)."目"指的是操作数的个数! C语言没有指定同一操作符的多个操作数的计算顺序(除了&& || ? : 和,).所以语句x = f() + g();的计算结果依赖不同的编译器. 1 /* 2 * 文件名: 3mu.c 3 * 描述:(1)一个表达式的类型取决于多个方面(表达式的操作

Standard C Episode 4

稍微简单的复杂数据类型:数组 计算机程序处理的对象是数据信息(计算机中的信息包括数据信息和控制信息),计算机内存可以存储大量信息,姑且可以认为只有存储在内存中的数据信息才是可 以使用的.内存由操作系统管理,程序要使用内存存储空间需要向操作系统申请并被成功分配后才可以使用,C语言提供的变量声明(定义)语句可以实现向操作系 统申请存储空间. C语言提供的变量声明(定义)语句实现向操作系统申请存储区(存储空间),变量名有"两个代表",一是代表所申请到的存储区,一是代表存储区里面存放的数 据信

Standard C Episode 6

字符串.字符串是以'\0'结尾的字符序列.C语言字符串在内存中的存储规则:按照串中字符出现的顺序在内存中连续存储,末尾是字符串结束符'\0'. 注:'\0'(查ASCII码表可知'\0'就是0)是表示字符串的字符,它的位置决定了一个字符串中有效字符的个数. 字符串常量.字符串常量在源程序词法记号中属于"文字",它和其他文字"数字.布尔文字.以及字符"一样.但区别是“字符串常量文字代表的是首字符地址”. 注:编译器编译时候会把源程序中重复出现的相同文字只存储一回.多个

Standard C Episode 8

C语言函数和程序结构 通过函数可以把大的计算任务分解成若干个较小任务,从而使得思路更加清晰,同时函数也大大提高了代码的复用率,提高了工作效率.要注意的是多函数之间应该尽可能地高聚合低耦合.另一方面,一个程序可以保存在一个或者多个源文件中.各个文件可以单独编译. 注意:一般地,头文件中不会放那些在程序运行时发生具体效应的语句.例如声明(定义)一个变量的语句是不会放在头文件中的.再例如结构体声明(定义)语句就可以放头文件里,但结构体变量声明(定义)语句是不会放在头文件中的. make工具可以用来进行

Standard C Episode 9

typedef关键字可以给数据类型起别名. 结构体.结构体可以如下定义一个结构体变量 1 /* 2 * 结构体 3 * */ 4 #include <stdio.h> 5 /*struct { 6 int age; 7 char gender; 8 float height; 9 } student;//声明(定义)无名结构体的同时定义了结构体变量student 10 */ 11 /*struct student { 12 int age; 13 char gender; 14 float h

Standard C Episode 10

标准库函数malloc/calloc/realloc以及free的堆内存分配与回收 1 /* 2 * malloc练习 3 * 4 * */ 5 6 #include <stdlib.h> 7 #include <stdio.h> 8 9 int main() 10 { 11 int *p_value = NULL; 12 13 p_value = (int *) malloc (1 * sizeof(int)); 14 if (p_value) { 15 printf("

Standard C Episode 7

编译预处理 #define可以定义宏.宏可以带参数,叫做带参数的宏,其参数叫做宏的参数. #undef 可以解除宏的定义. 1 /* 2 宏练习 3 */ 4 5 #include <stdio.h> 6 #define NEG( r) r = 0 - r 7 8 main() 9 { 10 int value = 4; 11 NEG(value); 12 printf("value是%d\n", value); 13 } 1 /* 2 宏练习 3 */ 4 #includ