函数(三):
局部变量和全局变量:
局部变量:在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外是不能使用这些变量的。这称为“局部变量”。即花括号内有效。
全局变量:程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数在函数内定义的变量是局部变量,而在函数之外定义的变量称为外部变量,外部变量是全局变量(也称全程变量)。全局变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。
表示符的作用域与可见性:
作用域:作用域之间可以存在包含关系。所有局部作用域被包含在全局全局作用域下、
全局作用域:范围广,从定义直到文件结尾都起作用。
1、全局变量可代替函数传参。
int a, b;
int add(void)
{
return a + b;
}
int main(void)
{
int i = 10, j = 20;
a = 10;
b = 20;
printf("%d\n",add());
return 0;
}
2、但全局变量传参比形参传参的耦合性高,尽量使用形参传参。
3、全局变量若未被初始化(.bss区)则一定为0,位于全局区或者静态区,以位模式清零。
4、函数名都具有全局作用域空间
局部作用域:花括号内,形参具有局部作用域
局部变量位于栈区
变量的生存期:从开辟空间到销毁空间这段时间称为生存期。
其又分为静态生存期与动态生存期
1、静态生存期:从开辟至程序结束的变量(全局变量、static int)具有静态生存期。
(static int:将动态变静态存入静态区与程序运行周期相同,但具有局部作用域且早已开辟好空间,在程序运行期间不会被销毁。)
int a = 10;
int b;
static int g_c;
static修饰的静态变量或函数,限制了其使用范围,其他文件无法调用。
2、动态生存期:局部变量具有动态生存期,栈区都具有动态生存期。
可见性:能否使用。
-
标识符必须先定义再使用;
-
同一作用域中不得出现同名标识符;
-
在没有包含关系的的不同作用域中定义的表示符,互不影响。
-
在两个或多个具有包含关系的作用域当中声明的同名标识符,外层标识符在内层不可见。
Auto变量:自动开辟、销毁空间,可被省略。堆区空间需要申请必须手动就不是auto。
register 寄存器:
在CPU中,为了提高读写效率,比RAM快成千上万倍。
extern 外部变量:
int add(void);
extern int a;
extern int b;
//声明不是定义
被register修饰的变量不能寻址。
外部函数:
先编译谁都行。
int add(int a,int b)
int main(void)
{
printf("%d\n",add(10,20));
return 0;
}
linux操作tips:
同时打开窗口,从中间切割窗口
上下切割。
:set mouse = a 鼠标可选择窗口。
头文件中只放声明不放定义
只需在main中# include” ”
第九章:预处理命令:
说明:ANSIC标准规定可以在 C源程序中加入一些“预处理命令”(preprocessor directives),以改进程序设计环境,提高编程效率。这些预处理命令是由 ANSI C统一规定的,但是它不是 C语言本身的组成部分,不能直接对它们进行编译(因为编译程序不能识别它们)。必须在对程序进行遁常的编译(包括词法和语法分析、代码生成、优化等)之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处理。
不带参的宏定义:
注:
1、宏名通常都大写 区别变量
2、gcc -E只做预处理不编译 -o 输出
3、预处理是无脑的文本替换 ,所以宏一般多加括号
带参宏:
举例:
#define ADD(a,b) a + b
int main(void)
{
printf("%d\n",ADD(10,20));
return 0;
}
注:
1、宏没有保护现场的功能,代码展开但未处理,效率高,但是代码复用性低。
2、带参宏 != 函数
3、勤加括号
示例:
求三角的面积
#include<stdio.h>
#include "sub.h"
#include<math.h>
#define S(a,b,c) (((a) + (b) + (c)) / 2.0)
#define AREA(a,b,c) sqrt(S(a,b,c) * (S(a,b,c) - (a)) * (S(a,b,c) - (b)) * (S(a,b,c) - (c)))
int main(void)
{
printf("%f\n",AREA(3,4,5));
return 0;
}
#include <> 与 “ ” 若填入的是绝对路径则两个无区别
若填入的是相对路径:则可使用<> 当前目录下的用” ”
能在源文件里包就包 延迟放。
条件编译:
1、#if 0 #endif 若#if 1 则有效代码
2、#ifdef K 定义了宏才有用
#define K;
int main(void)
{
#ifdef K
puts("Hello");
#endif
puts("World!");
return 0;
}
若需保存暂时不用的调试代码:
#define DEBUG
void printfArray(int a[], int len)
{
#ifdef DEBUG
printf("%lu\n",sizeof(a));
#endif
}
3、#ifndef 没定义就有效 #endif
头文件里就放这种结构,为防止重复包含。