局部变量和全局变量
局部变量:在一个函数内部定义的变量是内部函数变量,它只在本函数范围内有效。
全局变量:在函数之外定义的变量称为外部变量也就是全局变量,全局变量可以被本文件中其他函数所用。它的有效范围从定义变量的位置开始到本源文件结束。
标识符的作用域与可见性;
标识符生效的范围就是作用域。花括号内定义的标识符只在花括号内生效就是 局部作用域。
标识符定义和声明在花括号之外就是全局变量。尽量不用全局变量,会导致代码耦合性过高。
C语言的函数名都是全局作用域。
全局变量如果未被初始化,系统会自动补0。全局变量在全局区(静态区)
变量的生存期;
静态生存期:某个变量的生存期和程序的运行相同。数据存在全局区
动态生存期:某个变量的生存期和语句的运行相同。数据存在栈区
可以在函数内使用static 来修饰静态局部变量 将动态生存期变成静态生存期。
例
变量i具有静态生存期,但其可见性为局部。i为0
标识符的作用域具有包含特性,可以在作用域内包含作用域。即花括号内包含花括号。
所有的局部作用域包含在全局作用域下,
标识符的使用规则:
- 标识符必须先定义再使用。
- 同一作用域中不得出现同名标识符。
- 在没有包含关系的不同作用域定义的同名标识符 互不影响。
- 在两个或多个具有包含关系的作用域中定义的同名标识符 外层标识符在内层不可见。
register int i 可以将i放在高速寄存器内,此时不能使用&i取地址。因为寄存器内不能取地址。
在VIM命令页面使用:vsp 文件名 在左右视图打开另一个文件。
再使用:set mouse = a 两边文件都可以编辑。
创建 文件名.h 头文件, 头文件只放声明,不放定义。
exter 表明后面的代码是声明,不是定义。
在静态变量前 加 static 代表此静态变量只能在本文件使用,不能跨文件使用。
预处理命令
宏定义
#define N 10 定义了一个全局变量 N = 10 宏名都要大写。
宏的内容后面不加 分号 ;
gcc -e 只做预处理命令不编译。
预处理命令都是文本替换。
不带参宏
__Line__打印当前行数
__FILE__打印当前文件
带参宏:
#define ADD(a, b) a+b
文件包含
#include<fun.c> 将fun.c的全部内容复制插入到 #include<fun.c>命令处,
<> 系统到存放C库函数头文件的目录中寻找要包含的文件,称为标准方式。
“ ” 系统先在用户当前目录中寻找包含的文件,若找不到,再按标准方式查找 即 <> 的方法 一般来说用系统库函数 用<> 自己创建的文件 用“ “ 来节省时间。
条件编译
若指定的标识符已经被#define 命令定义过,则程序编译阶段编译程序段1;否则编译程序段2。其中else部分可以没有。
可以用来进行程序debug。
#ifndef _宏名 可以用来放在头文件防止重复定义。
#define _宏名
#endif 可以在每个头文件开头 写上 #ifndf _头文件名 末尾写上 #endif 来放在头文件重复引用。
代码练习:
e1.写一个文件来实现输入年份和月份打印当前月的日历,要求实现函数都写成头文件,主函数直接调用函数实现打印。
功能函数文件
calender.c
#include"calender.h"
int isLeapyear(int year)
{
if( year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
{
return 1;
}
else
{
return 0;
}
}
int daysOfTheMonth(int year, int month)
{
if(2 == month)
{
if(isLeapyear(year))
{
return 29;
}
else
{
return 28;
}
}
else if(4 == month || 6 == month || 9 == month || 11 == month)
{
return 30;
}
else
{
return 31;
}
}
int daysAfter1900(int year, int month)
{
int days2 = 0;
for(--month; month > 0; --month)
{
days2 += daysOfTheMonth(year,month);
}
int counter = 0;
int days1 = (year - 1900) * 365;
if(isLeapyear(year))
{
--counter;
}
for(year; year > 1900; --year)
{
if(isLeapyear(year))
{
++counter;
}
}
days1 += counter;
int days = days1 + days2;
return days;
}
int weekOfTheFirstDay(int year, int month)
{
return (daysAfter1900(year,month) + 1) % 7;
}
void printCalender(int year, int month)
{
puts(" Sun Mon Tue Wed Thu Fri Sat");
int i = weekOfTheFirstDay(year,month);
for(i *= 4; i > 0; --i )
{
putchar(' ');
}
int counter = weekOfTheFirstDay(year,month);
int j;
for(j = 1; j <= daysOfTheMonth(year,month); ++j)
{
printf("%4d",j);
++counter;
if(counter == 7)
{
counter = 0;
putchar('\n');
}
}
putchar('\n');
}
主函数文件
mian.c
#include"calender.h"
int main(int argc, const char *argv[])
{
int y,m;
printf("请输入年 月\n");
scanf("%d%d",&y,&m);
printCalender(y,m);
return 0;
}
头文件
calendar.h
#ifndef _CALENDER_H
#define _CALENDER_H
#include<stdio.h>
#include<string.h>
int isLeapyear(int year);
int daysOfTheMonth(int year,int month);
int daysAfter1900(int year, int month);
int weekOfTheFirstDay(int year, int month);
void printCalender(int year, int month);
#endif