C语言基础知识整理(三)

  1.局部变量:
(1)不同函数可以使用相同名字的变量。
(2)主函数不可以调用使用其他函数的中定义的变量,需要自己重新定义。
(3)形参是局部变量。
(4)在一个函数内部,可以在复合语句(分程序或程序块)中定义变量。
【注】:关于复合语句 的定义:pg184。


2.全局变量:
程序的编译单位是源程序文件,一个源文件可以包含一个或多个函数。


在函数内定义的变量是局部变量,而在函数之外定义的变量称为全局变量(外部变量);
【注】:在不必要时尽量不要使用全局变量:
    (1)全局变量在程序的执行全部过程中都会占用存储单元,不会解除内存单元。
    (2)这会使变量的通用性降低。


3.变量的存储类别:
存储类别指的是数据在内存中的存储方式:静态存储分配和动态存储分配;
具体包含4种:自动(auto),静态(static),寄存器(register),外部的(extern)。
根据存储类别,可以知道变量的作用域和生存期。


4.auto变量(动态存储方式)
函数中的局部变量,如果不专门声明为static存储类别,都是动态分配存储空间,这类局部变量为自动变量。
动态分配存储空间:形参和函数中定义的变量(包括在复合语句里定义的变量)


5.static声明局部变量:(静态变量)
  static声明的变量进行第二次变量调用时,继承第一次调用后的值。
  例:
     static int c = 3;     //第一次调用,c = 3,调用后c = 4;
     c += 1;               // 第二次调用,c = 4,调用后c = 5;


6.对静态局部变量的说明:
(1)静态局部变量是在编译时赋值的,即只赋初值一次,在程序运行的时候,他就已有初值。
     以后每次调用函数时都不再重新赋值,而是保留使用上一次调用结束时的值。


(2)如果定义局部变量时不赋值,对静态局部变量来说,编译时自动赋初值0(对于数值型变量)或空字符
    (字符变量)。对自动变量来说,如果不赋值,它的值是一个不确定的值,所以对自动变量,一定要赋值


(3)虽然静态局部变量在函数调用结束后,仍然存在,但是其他函数不能调用该静态变量。


7.register变量(寄存器)
 一般的变量存放和读取的方式:变量的值是存放在内存中,当程序中用到一个变量时,由控制器发出指令将内存中的该变量的值送到运算器
 中,如果需要存数,从运算器将数据存放到内存中。


寄存器的作用:C语言允许将局部变量的值存放在CPU中的寄存器,对于程序中使用频繁地变量,存放在寄存器
             里,可以提高程序的执行效率,这种变量称为寄存器变量。


 说明:
(1)只有局部自动变量和形参可以作为寄存器变量。
(2)一个计算机系统的寄存器数目是有限的,不能定义任意多个寄存器变量。
(3)局部静态变量(static)不能定义为寄存器变量,因为一个变量只能声明一种存储类别


8.extern:声明外部变量(全局变量)
 作用:用extern来扩展外部变量的作用域。
(1)在一个文件里声明外部变量:如果在某一全局变量之前想用该变量,就可以用关键字extern。


(2)在多个文件的程序中声明外部变量:由多个源程序文件组成的程序,其中一个文件
                                   要引用其他文件中已定义变量


9.用static声明外部变量(静态外部变量)
作用:限定某些文件中的全局变量只限在本文件使用,而不能被其他文件引用
     (各人可以独立的在其设计的文件中使用相同的外部变量名而互不影响)


10.声明和定义
(1)关于函数的声明和定义:
一个函数由两部分组成:声明部分和执行语句


声明部分:对有关的标识符(如变量,函数,结构体,共用体等)的属性进行说明
函数的声明是函数的类型,函数的定义是函数的本身
被调用函数的声明是放在主调函数的声明部分中,函数的定义是独立的部分


(2)关于变量的声明和定义:
声明部分出现的变量:(1)需要建立存储空间的(如int a);       //定义性声明(定义)
                   (2)不需要建立存储空间的(如 extern a);//引用性声明


广义的说:声明包含定义,但不是所有的声明都是定义
方便的说:把建立存储空间的声明叫做定义,不用建立存储空间的声明称为声明。


(3)关于外部变量的声明和定义:
外部变量的定义只能有一次,他的位置在所有函数之外,赋值是在定义中进行;
而同一 文件里,外部变量的声明可以有多次,哪个函数用就在哪个函数里声明;或在外部变量定义点之前
所谓声明,作用是声明该变量是一个已在后面或其他文件已定义的外部变量。extern只能用于声明,不是定义


static声明一个变量的作用:
(1)对全局变量,该变量只限于本文件使用
(2)对局部变量,该变量在整个执行过程中不释放,分配的空间始终存在。


11.预处理命令
C语言源程序加入一些“预处理命令”,可以改进程序设计环境,提高编译效率。但是它不是C语言本身的组成
部分,不能直接对他进行编译(因为编译程序不能识别它们),必须在程序进行通常编译
(包括词法和语法分析)之前,对程序中一些特殊的命令进行“预处理”。


如:在程序中,#define定义一个符号变量A,则在预处理时将程序里的所有A都置换成指定的字符串。
   若程序中用#include命令包含一个文件“stdio.h”,则预处理时将stdio.h文件中的实际内容代替该命令。


程序在预处理之后,由程序编译预处理后的源程序进行通常的编译,得到可执行的目标代码。


C语言包括:预处理、编译、链接等部分,在进行编译时一气呵成。


【注】【重要点】C语言与其他高级语言的一个重要区别是可以使用预处理命令和具备预处理功能。


C提供的预处理功能主要包含:
(1)宏定义
(2)文件包含
(3)条件编译
分别使用宏定义命令,文件包含定义,条件编译命令来实现;这些命令以“#”开头。


12.不带参数的宏定义
     用一个指定的标识符(即名字)来代表一个字符串,他的一般形式为:
     #define(宏定义命令)  标识符(宏名)  字符串(宏展开)
     例:#define PI 3.14159      //用PI代替3.14159


说明:
(1)宏名一般用大写表示,用以区分变量名,但这不是规定。


(2)使用宏名来代替字符串可以降低程序的工作量;当改变宏定义变量时,只要改#define命令行,一改全改。


(3)宏定义就是简单的置换,在预处理时,不作任何语法检查。只有在编译已被宏展开后的源程序时才有可能
     发现语法错误并举报。
(4)宏定义不是C语言,一次在句末不用加上“;”。


(5)#define出现在程序中函数的外面。


(6)可以用#undef命令终止宏定义的作用域。


(7)在进行宏定义时,可以引用已定义的宏名,层层置换。


13.带参数的宏定义
带参数的宏定义不是进行简单的字符串置换,还要进行参数替换;
定义的一般形式: #define 宏名(参数表) 字符串   //字符串中包含在括号中指定的参数


对带参数的宏定义是这样定义的:
如果有带实参的宏(如S(3,4)),则按#define命令行中指定的字符串从左到右进行置换。
如果字符串中包含宏的形参(如S(a,b)中的a,b)则将程序里的相关实参(常量,变量,表达式)代替形参
如果宏定义中的字符串中字符不是参数字符,则保留,就这样形成置换的字符串。


说明:
(1)对带参数的宏展开只是将语句中的宏名后面括号里的实参字符串代替#define命令行的形参【注】pg208


(2)在宏定义时,在宏名和带带参数的括号之间不加空格。


14.带参数的宏定义与函数的区别:
(1)函数调用时,先求出实参表达式的值,然后带入形参,而使用带参数的宏只是进行简单的字符置换


(2)函数调用是在程序运行时处理的,为形参分配临时的内存单元;而宏展开则是在编译之前进行的,展开时
     并不分配内存空间,不进行值的传递处理,有没有“返回值”的概念。


(3)对函数中的实参和形参都要定义类型,而这类型要求一致,如不一致,要求强制类型转换;而宏不存在
    类型问题,宏名无类型,它的参数也没有类型,宏定义时,字符串可以是任意类型的数据。


(4)调用函数只可以得到一个返回值,而宏可以得到多个值(宏的参数值都可以通过该宏其他参数来求得)


(5)使用宏次数多时,宏展开后的源程序会变长,而函数不会使源程序变长;


(6)宏替换不占运行时间,只占编译时间,而函数调用占运行时间(分配单元、保留现场、值传递、返回)。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值