目录

  • 1 第一章 C语言简介
    • 1.1 C语言前世今生
    • 1.2 主流开发环境介绍
    • 1.3 第一个小程序解析
    • 1.4 常见编译错误
    • 1.5 章节知识点小结
  • 2 算法基础
    • 2.1 算法-程序的灵魂
    • 2.2 算法的描述-流程图
  • 3 数据类型与运算符
    • 3.1 数据描述
    • 3.2 运算符和表达式1
    • 3.3 运算符和表达式2
    • 3.4 章节知识点小结
  • 4 顺序结构程序设计
    • 4.1 输入和输出
    • 4.2 顺序结构程序设计
    • 4.3 章节知识点小结
  • 5 选择结构程序设计
    • 5.1 关系运算符和关系表达式
    • 5.2 逻辑运算符和逻辑表达式
    • 5.3 if语句
    • 5.4 条件运算符
    • 5.5 switch语句
    • 5.6 章节知识点小结
  • 6 循环结构程序设计
    • 6.1 while循环结构
    • 6.2 do_while循环结构
    • 6.3 for循环结构
    • 6.4 循环的嵌套
    • 6.5 break语句和continue语句
    • 6.6 章节知识点小结
  • 7 数组
    • 7.1 一维数组
    • 7.2 二维数组
    • 7.3 字符数组
    • 7.4 章节知识点小结
  • 8 函数
    • 8.1 子程序设计
    • 8.2 函数定义
    • 8.3 函数的调用
    • 8.4 局部变量和全局变量
    • 8.5 参数传递
    • 8.6 函数递归调用
    • 8.7 章节知识点小结
  • 9 指针
    • 9.1 指针的基本概念
    • 9.2 指针变量的定义及引用
    • 9.3 通过指针引用数组元素
    • 9.4 指向多维数组的指针和指针变量
    • 9.5 用指向数组的指针作函数参数
    • 9.6 指针与字符串
    • 9.7 函数指针和指针函数
    • 9.8 章节知识点小结
  • 10 用户自己建立数据类型
    • 10.1 定义和使用结构体变量
    • 10.2 使用结构体数组
    • 10.3 结构体指针
    • 10.4 章节知识点小结
  • 11 编译预处理
    • 11.1 宏定义预处理
    • 11.2 文件包含预处理
    • 11.3 条件编译预处理
    • 11.4 章节知识点小结
  • 12 文件
    • 12.1 文件的基本知识
    • 12.2 文件的基本操作
    • 12.3 章节知识点小结
局部变量和全局变量



变量存储类型

如果要使用好变量,除了学习变量的运算性质和变量的存储形式以外,变量的生存时间和变量在内存中的存储位置也应是我们学习C语言时应该深入了解的内容之一。

在前面学习数组时,我们就已经了解到:变量应该要从“数据类型”和“存储类型”两个方面才能比较深入地进行描述,由于前面我们已经学习了“数据类型”,所以本节主要学习“存储类型”的基本知识。

变量的存储类型主要可以分为四种,即:动态存储、外部存储、静态存储和寄存器变量,C语言中分别用autoexternstaticregister加以说明。存储类别说明符主要是用来告诉编译程序,其后的变量应该如何存储。

如果从变量的生存时间上考察变量,我们可以表示为:

 

                                静态存储变量:在程序运行期间分配固定的存储空间

变量的生存周期

                                 动态存储变量:程序运行时根据需要进行动态分配存储空间的方式


变量的存储类型说明要放在变量的数据类型说明之前,即以下形式:

存储类型   数据类型 变量名


局部变量存储方式:

1) 自动变量(auto型)

格式:auto 类型名   变量名

动态变量存储在动态存储区中,主要是指函数的动态局部变量和形式参数。

动态变量在函数调用开始就动态分配内存单元,在函数调用结束时,由系统收回并释放其内存空间。

因为普通的局部变量均隐含地被认为是auto型,所以一般很少使用auto说明符。

auto int b=3;  (注意:auto可以省略或默认类别为auto)

如上可写成  int b=3;

2) 局部静态变量

静态变量存储在静态数据区,在其所在的函数和程序中是永久变量,所以如果想在调用函数后保留变量值,下次调用时继续使用,则应用静态存储。

格式:static  类型名变量名

例8.6.1】静态变量示例

int f(b)

int b;

{

 auto int a=0;

  staticint c=3;                 //  分析:         b      c   

  a=a+1;c=c+1;                //  第一次开始:    0      3  

  return(a+b+c);}              //  第一次结束:    1      4  

main()                        //  a+b+c=7   

{

 int b=2,i;                    //  第二次开始:    0     4  

  for(i=0;i<3;i++)              //  第二次结束:    1      5  

 printf(" %d ",f(b) );           //  a+b+c=8 

}                            //  第三次开始:    0      5  

                             //  第三次结束:    1     6  

                             //  a+b+c=9  


说明:

(1) 局部静态变量属静态存储类别。(程序运行期间存储数据不释放)而自动变量不占自动空间(调用结束释放)。

(2) 局部静态变量在编译初期赋值,以后只保留上次调用时值,而自动变量每调用一次重新赋值。

(3) 在定义局部变量时如不赋初值。

   静态变量:自动为0

   动态变量:值不固定(因为每次结束释放,下次分配)。

(4) 在第九章讲到数组时,会介绍到只有全局变量和局部静态变量才可以对数组初始化。

(5) 局部静态变量使用情况。

a.需保留上一次调用结束时值;

b.数值初始化时。


3) 寄存器变量(register型)

格式:register  类型名 变量名

说明:

(1) 由于寄存器变量存储在计算机的CPU中,所以使用寄存器变量要比使用内存变量的操作要快得多,即可以提高执行效率。

(2) 寄存器变量的类型仅限:int, char或指向int,char的指针。

(3) 寄存器变量仅适用局部变量或函数的形式参数。

(4)C规定寄存器变量的数目不能超过3个,多余的将按auto处理


例8.6.2】观察使用寄存器变量作循环控制变量时程序执行时间的变化。

#include  "stdio.h "

#include  "time.h "

unsigned int a,delay;

void main(void)

{

 register unsigned int b;

 long  t;

 t=time('\0' );

 for(delay=0;delay<1000;delay++)

 for(a=0;a<64000;a++)

  printf("\n Time_escaping for NON-register loop:%ld ",time('\0')-t);

 t=time('\0' );

 for(delay=0;delay<1000;delay++)

   for(b=0;b<64000;b++)

 printf("\n Time_escaping for register loop:%ld ",time('\0')-t);

 return ;

}

请大家自己运行下该程序,如果本程序在档次较低的旧机器上运行结果会非常明显,即两次结果差别很大


说明:对现在的计算机来说,这种类型的变量基本上和自动类型变量一样了,而且计算机内存管理中,由于寄存器资源十分宝贵,计算机系统也不完全按用户程序定义的这种类型变量来指定类型了。



全局变量的存储类型

1) 外部变量(extern型)

格式:extern  类型名变量名

这种变量我们在上一节例子中已经学习过。

在定义全局变量时,如果没有存储类型说明符,则认为它是隐含的extern型变量,系统在编译时为静态存储区的extern型全局变量分配内存单元。若一个变量使用了extern说明,则系统不再分配内存单元,而是从本程序中去查找同名的全局变量(即外部变量)。

C语言要求程序的全局变量只能在某个程序文件中说明一次。因此当希望在一个程序文件中使用另外文件中说明过的全局变量时,必须在该全局变量前用extern进行说明,这样在编译这些文件时,系统对程序中的extern说明的全局变量将不再分配存储单元,而只为无extern说明的全局变量分配存储单元,以便连接时供其他程序文件使用。

2) 静态全局变量(static型)

格式:static  类型名  变量名

静态全局变量和普通全局变量的区别在于:它只说明它的程序在本程序中有效,即虽然它是全局变量,但是其他程序文件中的程序并不知道它的存在,无法改变其内容,所以在静态局部变量仍不能满足编程要求时,可以通过建立独立的小程序文件模块,其中只使用必要的静态全局变量以及使用这些变量的函数,并独立编译这个程序文件后,再进行程序连接,就可以放心使用这个程序文件中的函数,而不必担心全局变量可能带来的不利影响。


8.6.1】选择一个整数随机数序列的“种子”,产生10 个随机数。

解题思路:

设计一个全局静态变量ran_num作为随机数序列的“种子”,其初值在主函数中输入。同时设计一个随机数产生函数random_num,其功能是产生一个随机整数,在主函数中循环调用10函数random_num,并对得到的随机数进行整除1000,整除后的结果作为最后随机值。

#include  "stdio.h "

static int ran_num;

void ran_num_seed(int seed);

int random_num(void);

void main( )

{

 int a;

 printf("\n Input Random number seed:");

 scanf("%d",&ran_num);

 for(a=0;a<10;a++)

 {

    if(a%5==0) printf("\n");

    printf("%10d",random_num( )/1000);   

 }

 printf("\n");

 return ;

}

int random_num(void)

{

 ran_num=ran_num*1023+2323;

 return(ran_num);

}








下面以两个例子进行说明。

例8.5.1】计算34567的累加和,并分别显示累加结果。

解题思路:

设计一个全部变量sum,分别用来存放34的累加和,345的累加和,3456的累加和,34567的累加和,求和功能通过函数total来完成,在主函数中循环调用该函数,输出每步累加和的结果,循环变量初值和终值通过对全局变量ab初始化进行设置。另外设计一个函数display_scope完成表头输出效果。

程序代码:

#include "stdio.h "

int sum;                                      //全局变量

void display_scope(void);

int total(int x);

void display(void);

void main()                       //主函数 

{

 extern int a,b; 

 //由于外部变量ab在后面定义,根据C语言规定,在前面使用必须要先说明

 int count;                                  //局部变量

 sum=0;

 display_scope();

 for(count=a;count<=b;count++)    //a,b已在本函数外被初始化为38

   { total(count);

     printf(" Start from %d,End at %d: ",a,count);

     display();

   }

 return ;

 }

int a=3,b=8;                                                  //全局变量,其后均有效

void display_scope(void)         //表头打印函数

 {

  int count;                                       // 局部变量,本函数有效

  for(count=1;count<=30;count++) printf(" -" );

  printf(" \n  The Scope ofSumation:From %d to %d:\n ",a,b);

  for(count=1;count<=30;count++) printf(" -" );

  printf("\n ");

 }

int total(int x)                                             //求累加结果

{  

  sum=sum+x;                       //  sum为全局变量,所以本函数内外均有效

}

void display(void)                                   //  显示累加结果

{

int a;                                                     //此处a为局部变量,本函数有效。由于与全局变量同名

                                                        //所以全局变量a在此无效

  for(a=1;a<=5;a++) printf(" . ");

  printf(" The current sum is %d\n ",sum);

}


运行结果:


在本例中,我们应该可以看到:

(1) 在一个函数中,如果全局变量与局部变量同名,则只有局部变量有效,即同名局部优先。

(2)如果一个函数使用的全局变量在该函数后说明,则应用extern进行外部变量说明,如果在其之前已说明,则无需进行附加说明