无题

全局变量

  • 定义在函数外面的变量就是全局变量
  • 全局变量具有全局的生存期和作用域
  • 它们与任何函数都没有关系,但是在任何函数的内部都可以使用它们
  • 全局变量默认初始化值是0,指针变量会得到NULL值
  • 只能用已知的值去初始化全局变量,因为它们的初始化在Main函数之前
  • 如果函数内部存在与全局变量同名的变量,那么全局变量会被覆盖

静态本地变量

  • 在本地变量定义时加上static修饰符就能成为静态本地变量
  • 当函数离开的时候,静态本地变量会继续存在并保持其值
  • 静态本地变量的初始化只会在第一次进入这个函数的时候做,以后进入函数时会保持上次离开时候的值
  • static是特殊的全局变量,与全局变量在内存的同一块地址,具有全局生存期,但只有局部作用域

  • 以#开头的是编译预处理指令,不是C语言自带的东西

  • 使用#define定义宏,#define <名称> <值>

  • 在编译前通过完整的文本替换方式将名称替换对应的值

  • 宏可以嵌套使用,超过一行的值需要在行末加上\

  • 在值中写注释不会被当作值的一部分

还有一些预定义的宏

描述
_LINE_ 这会包含当前行号,一个十进制常量。
_FILE_ 这会包含当前文件名,一个字符串常量。
_TIME_ 当前时间,一个以 “HH:MM:SS” 格式表示的字符常量。
_DATE_ 当前日期,一个以 “MMM DD YYYY” 格式表示的字符常量。
_STDC_ 当编译器以 ANSI 标准编译时,则定义为 1。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main() {

printf("File :%s\n", __FILE__);
printf("Date :%s\n", __DATE__);
printf("Time :%s\n", __TIME__);
printf("Line :%d\n", __LINE__);
printf("ANSI :%d\n", __STDC__);
/*
* File :/Users/zhboat/CLionProjects/hon/main.c
* Date :Jun 14 2020
* Time :15:37:03
* Line :8
* ANSI :1*/
return 0;
}

带参数的宏

  • 可以像函数一样使用,将未来的参数传递到预处理指令中

  • 格式#define <名称(参数)> <值>

  • 在其他函数中调用#define的名称加()时传递的值会回到#define中

  • 使用参数的时候,整个值需要加上括号,每个使用参数的地方也需要加上括号

  • 可以嵌套组合使用,也可以带上多个参数

#define MIN(a,b) ((a)>(b)?(b):(a))判断两个数中最小的值,如果a大于b,则最小数就是b,否则就是a

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

#define cube(i) ((i) * (i + 1) * ( i + 2))

// i = 5, i + 1 = 6, i + 2 = 7
int main() {
int i;
scanf("%d", &i); // i = 5
printf("%d", cube(i)); // 5 * 6 * 7 = 210
return 0;
}

#&##

字符串常量化运算符(#)

在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)。在宏中使用的该运算符有一个特定的参数或参数列表

标记粘贴运算符(##)

宏定义内的标记粘贴运算符(##)会合并两个参数。它允许在宏定义中两个独立的标记被合并为一个标记

头文件

  • 头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享。有两种类型的头文件:程序员编写的头文件和编译器自带的头文件。

  • 把函数原型放到一个头文件(以.h结尾)中,在需要调用这个函数的源代码文件(.c)中#include这个头文件,就能让编译器在编译的时候知道函数的原型

#include

  • 与宏一样,#include也是一个编译预处理指令,在编译之前就处理好了

  • 它的作用是把头文件中的全部文本原封不动得插入到#include所在的位置

  • #include ""要求编译器首先在当前目录寻找头文件,如果没有就去其他地方寻找,#include <>用于引用系统头文件,在系统目录的标准列表中搜索

  • 在使用和定义函数的地方都应该有#include 头文件,任何源文件除了main函数都应该有对应的同名头文件,把所有对外公开的函数的原型和全局变量的声明都放进去

不对外公开的函数

  • 在函数前面加上static就能让他成为只能在所在的源代码中才能被使用的函数

声明

  • 对于变量的声明,格式:extern 变量类型 变量名

  • 函数原型 变量声明 结构声明 宏声明 枚举声明 类型声明 …等,这些声明都是不产生代码,只有在定义的时候才产生代码

重复声明

  • 如果头文件中有结构的声明,那么很可能会在同一个源代码中被#include很多次,为了避免这种情况的发生,需要用到标准头文件结构

  • 标准的做法是把文件的整个内容放在条件编译语句中

    1
    2
    3
    4
    5
    #ifndef 头文件
    #define 头文件
    声明
    ...
    #endif
    1
    2
    3
    4
    5
    6
    7
    #ifndef POINT_H
    #define POINT_H
    struct point {
    int x;
    int y;
    };
    #endif

评论