linuxC学习第二十一天

一、预编译相关

1、define

(1)define的用法
(1)#define定义宏常量可以出现在代码的任何地方
(2)从#define宏定义位置开始,以后的代码就都可以使用这个宏了
(3)编译器会在预处理的时候用真身替换宏

(2)定义函数
#define SUM(a, b) ((a)+(b))

(3)撤销定义
#Undef SUM

(4)内置宏
LINE:表示正在编译的文件的行号
FILE:表示正在编译的文件的名字
DATE:表示编译时刻的日期字符串
TIME:表示编译时刻的时间字符串
FUNCTION:表示编译时候所在的函数

2、ifdef

1、ifdef条件编译有3种方式
(1)#ifdef…#else…#endif
#ifdef 标识符
程序段1
#else
程序段2
#endif

它的功能是:如果标识符已被#define命令定义过,则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式种的#else可以没有,既可以写为:
#ifdef 标识符
程序段
#endif

(2)#ifdef…#else…#endif
#ifndef 标识符
程序段1
#else
程序段2
#endif

与上一种形式的区别是ifdef改为ifndef。它的功能是:如果标识符未被#define命令定义过,则对程序段1进行编译;否则对程序段2进行编译。这与第1种形式的功能正好相反

(3)#if…#else…#endif
#if 常量表达式
程序段1
#else
程序段2
#endif

它的功能是:如果常量表达式的值为真(非0),则对程序段1进行编译;否则对程序段2进行编译。因此可以使程序在不同条件下编译,完成不同的功能。

3、#和##

1、功能
#用于在与编译期间将宏参数转化为字符串
##用于在预编译期间粘连两个符号

二、一些关键字

1、typedef(关键字)

1、功能:
使用关键字 typedef 可以为类型起一个新的别名
2、给普通类型起名字
typedef int INTEGER;
注意要加 ;

3、给数值类型起名字
typedef char ARRAY20[20];

4、给结构体类型起名字2种形式
(1)
typedef struct stu
{
char name[20];
int age;
char sex;
} STU;
(2)
struct stu
{
char name[20];
int age;
char sex;
} ;
typedef struct stu STU

5、给函数指针类型起名字
typedef int(*PFunc)(int a,int b)
6、与define的区别
typedef 在表现上有时候类似于 #define,但它和宏替换之间存在一个关键性的区别。正确思考这个问题的方法就是把 typedef 看成一种彻底的“封装”类型,声明之后不能再往里面增加别的东西。

(1) 可以使用其他类型说明符对宏类型名进行扩展,但对 typedef 所定义的类型名却不能这样做。如下所示:
#define INTERGE int
unsigned INTERGE n; //没问题

typedef int INTERGE;
unsigned INTERGE n; //错误,不能在 INTERGE 前面添加 unsigned

(2) 在连续定义几个变量的时候,typedef 能够保证定义的所有变量均为同一类型,而 #define 则无法保证。例如:
#define PTR_INT int *
PTR_INT p1, p2;
经过宏替换以后,第二行变为:
int *p1, p2;
这使得 p1、p2 成为不同的类型:p1 是指向 int 类型的指针,p2 是 int 类型。

相反,在下面的代码中:
typedef int * PTR_INT
PTR_INT p1, p2;
p1、p2 类型相同,它们都是指向 int 类型的指针。

2、return(关键字)

用来终止一个函数并返回其后面跟着的值

3、static(关键字)

1、用于修饰变量(静态变量)
变量又分两种类型
(1)局部变量:修饰局部变量的时候,可以增加局部变量的寿命。加上staric就是静态变量了,存放在数据区,不在是栈。当出栈后这个变量的值还是存在着,直到程序结束才释放掉
(2)全局变量:修饰全局变量的时候,可以令这个全局变量只能在本文件中使用,其他文件就算加上extern也无法使用(就是隐藏了起来)。

2、用于修饰函数(静态函数)
令函数只能在本文件中使用,好处在不同的人编写函数时,不用怕名字重复。

4、const(关键字)

1、用于修饰变量
将变量改成只读属性,不能通过修饰变量名来改变变量空间的值
注意:const不能通过变量名改变变量空间的值但可以通过其他方式改变,例如指针(一般不推荐)

2、修饰数组
定义或说明一个只读数组可采用如下格式:
int const a[5] = {1,2,3,4,5}; 或 const int a[5] = {1,2,3,4,5}

3、修饰指针
const int * p; // p可变,p指向的对象不可变
int const * p; // p可变,p指向的对象不可变
int * const p; // p不可变,p指向的对象可变
const int * const p; // 指针p和p指向的对象都不可变

这里给出一个记忆和理解的方法:
先忽略类型名(编译器解析的时候也是忽略类型名),我们看const离哪个近,“近水楼台先得月”,离谁近就修饰谁。
const (int) p //const 修饰p,p是指针,p是指针指向的对象,不可变。
(int) const * p; //const 修饰
p,p是指针,p是指针指向的对象,不可变。
( int) * const p;//const 修饰p,p不可变,p指向的对象可变,即
p可变
const ( int)* const p; // 前一个const修饰*p,后一个const修饰p,指针p和p指向的对象都不可变

4、修饰数组
const修饰也可以修饰函数的参数,当不希望这个参数值在函数体内被意外改变时使用。格式如下:
void Fun(const int *p)

5、修饰返回值
const也可以用于修饰函数的返回值,返回的数值不能改变,格式如下:
const int Fun(int *p)

5、extern(关键字)

1、 变量声明
变量声明就是给变量一个名字,让下面的程序知道有这个变量去其他文件中找。
注意的是变量声明只有名字,没有空间。
2、extren:用于变量的声明,当你使用多个文件时想要用其他文件中定义的变量就要用extern进行变量的声明

猜你喜欢

转载自blog.csdn.net/weixin_43360263/article/details/84679026