c语言----变量和预处理

c语言----变量和预处理

文章目录

  • c语言----变量和预处理
    • 全局变量
    • 全局变量初始化
    • 静态本地变量
    • *返回指针的函数
    • 编译预处理指令
      • `#define`
      • 没有值的宏
      • 预定义宏
      • 带参数的宏
        • 带参数宏的原则
      • #include后面到底使用“”还是<>?
      • 声明

全局变量

  1. 定义在函数外边的变量是全局变量
  2. 全局变量具有全局的生存期和作用域
  3. 他们和任何函数都无关
  4. 在任何函数都可以使用它

全局变量初始化

  1. 没有做初始化的全局变量会得到0值
  2. 指针会得到NULL
  3. 只能用编译时刻已知的值来初始化全局变量
  4. 它们的初始化在main主函数发生前完成

如果函数内部存在与全局变量同名的变量,则全局变量会被隐藏(优先使用局部变量)

静态本地变量

  1. 在本地变量定义时加上static修饰符就会变成静态本地变量
  2. 当函数离开的时候,静态本地变量会继续存在并保持其值
  3. 静态本地变量的初始化只会在第一次进入这个函数时做,,以后进入这个函数会保持上次离开的值
#include"stdio.h" 
int f(); 
int i=0;
void main()
{
	for(i=0;i<10;i++)
		f();
}
int f()
{
	static int a=0;
	printf("%d次调用a的值%d\n",i,a);
	a+=2;
	return a;
}

结果:

c语言----变量和预处理_第1张图片

如果a不是静态变量(static int a=0变为int a)

结果:
c语言----变量和预处理_第2张图片
实际上静态本地变量就是特殊的全局变量。但是作用域只能在定义它的函数内部

*返回指针的函数

  1. 返回本地变量是危险的。因为一旦子函数完成运算,其里面的本地变量的地址空间会被收回,然后分配给后续函数使用
  2. 返回全局变量或者静态本地变量的地址是安全的
  3. 返回在函数内的malloc的内存是安全的,但容易造成问题
  4. 最好的做法是返回传入的指针

## 小贴士

  1. 不要使用全局变量在函数间传递参数和结果
  2. 尽量避免使用全局变量

编译预处理指令

  1. #开头的就是编译预处理指令
  2. 他们不是c语言的成分,但是c语言程序离不开他们

#define

  1. 用法:#define <名字> <值>
  2. 注意:没有结尾的分号,因为不是c语句
  3. 名字必须是一个单词,值可以是各种东西
  4. c语言在编译器编译之前,编译预处理程序会打程序中的名字全部换为值

什么叫做宏呢?

按照上面定义出来的东西叫做宏

  1. 如果一个宏的值中有其他宏的名字,也是会被替换的
  2. 如果一个宏的值超过一行,最后一行之前的行末尾加\
  3. 宏的值后面出现的注释不会当成宏的一部分
#include"stdio.h" 
#define PI 3.141596
#define PI_1 2*PI		//宏中带宏 
#define PRT printf("PI=%f\n",PI);\		//定义多行宏 
			printf("2*PI=%f\n",PI_1);
void main()
{
	PRT
}

结果:

c语言----变量和预处理_第3张图片

没有值的宏

#define _DEBUG

这类宏是用来条件编译的,后面的其他预处理指令来检查这个宏是否已经被定义了

预定义宏

描 述
DATE 源文件的编泽口期,用 “Mmm dd yyy”形式的字符串常量表示
FILE 当前源文件的名称,用字符串常量表示
LINE 当前源文件中的行号,用十进制整数常量表示,它可以随#line指令改变
TIME 当前源文件的最新编译吋间,用“hh:mm:ss”形式的宁符串常量表示
STDC 如果今前编泽器符合ISO标准,那么该宏的值为1,否则未定义

带参数的宏

#include"stdio.h" 
#define cube(x) (x)*(x)*(x)//括号尽量不要少
void main()
{
	printf("%d\n",cube(5+5));	//宏定义中的x用5+5代替 
} 
带参数宏的原则

一切要有括号:整个值要有括号,参数出现的每一个地方都要括号

#define cube(x) ((x)*3.14*3.14)	//正确使用

#define cube(x) (x)*3.14*3.14	//错误使用
#define cube(x) (x*3.14*3.14)	//错误使用

可以带有多个参数,也可以嵌套使用

#define min(a,b) ((a)>(b)?(a):(b))

注意:使用宏不能加分号,因为我们一般在定义宏时就加了分号

  1. 在大型程序的代码中使用普遍
  2. 可以非常复杂,如“产生”函数
  3. 部分宏会被inline 函数代替

#include后面到底使用“”还是<>?

​ ""要求编译器首先在当前目录(.c所在的目录)找寻这个文件,如果没有就在编译器指定的目录去找

​ <>让编译器只在指定目录下找

编译器自己知道自己的标准库的头文件在哪里

一般的做法就是任何.c都有和它同名的.h,把所有的对外公开的函数原型和全局变量的声明都放进去

声明

怎么声明一个全局变量,使其在各个.c文件被使用?

extern int a//声明一个全局变量(不能初始化

int a//定义一个变量

怎么保证.h文件只被编译一次?

我们知道所有变量只能被编译一次的。当变量被定义在.h中,当多次调用这个.h文件。在编译时会多次编译

//标准头文件结构
#ifndef _MAX_H_		//如果没有定义_MAX_这个宏的话,就定义这个宏,如果存在直接跳到endif
#define _MAX_H_


#endif

保证.h文件只被编译一次?**

我们知道所有变量只能被编译一次的。当变量被定义在.h中,当多次调用这个.h文件。在编译时会多次编译

//标准头文件结构
#ifndef _MAX_H_		//如果没有定义_MAX_这个宏的话,就定义这个宏,如果存在直接跳到endif
#define _MAX_H_


#endif

c语言----变量和预处理_第4张图片

你可能感兴趣的:(c语言)