条件编译、多文件编程、结构体

条件编译

条件编译可以在编译的时候从几组语句中选择一组编译而忽略其他组,

#ifdef/#ifndef...
#else...
#endif

这个结构可以根据一个宏名称是否被定义过从两组语句中选择一组编译,最开始的预处理指令都应该从两个里选择一个,不论选择哪一个都应该在后面写一个宏名称。如果最开始的预处理指令选择#ifdef就表示后面的宏名称被定义的时候编译前一组语句否则编译后一组语句,如果最开始的预处理指令选择#ifndef效果和#ifdef刚好相反。

练习:编写点菜程序,要求能编译成两个不同的版本

1.代表龙虾

2.代表小鸡炖蘑菇

(有、没有、真没有)

/*
 *
 *点菜程序
 *
 * */
#include<stdio.h>
int main (){
	int order = 0;
	printf("请点菜:");
	scanf("%d",&order);
#ifdef 		ZHAOBENSHAN
	if (order == 2){
		printf("真没有\n");
	}
	else {
		printf("没有\n");
	}
#else
	if (order == 2){
		printf("没有\n");
	}
	else {
		printf("有\n");
	}
#endif
	return 0;
}

#if...
#elif(任意多次)...
#else...
#endif

以上结构可以实现条件编译的效果,它可以根据任意逻辑表达式从多组语句中选择一组编译。

“#if”和“#elif”后都需要写逻辑表达式,这些逻辑表达式里可以使用任意逻辑操作符,这些逻辑表达式的作用和if分支里逻辑表达式的作用一样。

多文件编程

多文件编程的时候任何一个函数只能属于一个文件,一个文件里可以包含多个函数,多文件编程基本步骤:

1.把所有函数分散在多个不同的源文件里(主函数通常单独占一个文件)。

2.为每个源文件编写配对的以.h作为拓展名的头文件(主函数所在的源文件不需要配对的头文件)只要不分配内存的内容都可以写在头文件里,头文件里至少应该包含配对源文件里的所有函数声明。

3.修改所有源文件,在源文件里使用#include预处理指令包含必要的头文件(配对头文件是必要头文件,如果源文件里使用了某个头文件里声明的函数则这个头文件也是必要头文件)。

编译多文件程序的时候需要在gcc命令后列出所有源文件的路径。

Makefile

可以把多文件程序的编译过程记录在Makefile文件里,然后使用make工具根据Makefile文件的内容进行编译。

Makefile里每个编译命令前都应该用tab键而不是空格键。

头文件内容如果应该被包含在条件编译预处理指令中间,这样可以避免编译的时候哦反复多次重复编译同一个头文件的内容。第一个预处理指令必须是#ifndef,头文件使用的宏名称应该根据文件名称变化得到。

Makefile简单书写如下,

a.out : main.o func.o
		gcc main.o func.o
main.o : main.c
		gcc -c main.c
func.c : func.c
		gcc -c func.c


练习:编写函数从键盘得到一个整数并把这个整数传递给调用函数,用多文件编程实现。

/*主函数*/
#include<stdio.h>
#include "11add.h"
int main (){
	int num = 0,num1 = 0;
	printf("请输入两个数字:");
	scanf("%d%d",&num,&num1);
	printf("%d\n",add(num,num1));
	return 0;
}

/*加法函数*/
#include"11add.h"
int add (int num ,int num1){
	return num + num1;
}

/*加法函数头文件*/
#ifndef 	_ADD_H_
#define		_ADD_H_
int add(int,int);
#endif 		//_ADD_H_

全局变量补充

如果希望从一个源文件里使用另外一个源文件里声明的全局变量就需要使用extern关键字再次声明这个全局变量,这种使用extern关键字声明的语句不会分配内存,他们通常写在头文件里。不可以跨文件使用静态全局变量。

结构体

C语言里可以在一个存储区里记录多个数字,这种存储区的类型叫结构体类型;这种类型需要创建出来后才能使用,结构体类型的存储区里包含多个子存储区,每个子存储区可以用来存放一个数字,结构体的不同子存储区也可以是结构体类型的存储区。

结构体声明语句可以用来创建结构体类型,声明结构体类型的时候需要使用struct关键字。结构体声明语句里包含多个变量声明语句,这些变量叫做结构体的成员变量,每个成员变量代表一个子存储区。成员变量的声明语句不会分配内存,它们只是用来表示子存储区的类型名称(成员变量不可以初始化),C语言里结构体不可以包含函数,结构体声明语句可以写在任何地方,包括头文件里。

可以把结构体作为类型声明变量,这种变量叫做结构体变量。把结构体作为类型的时候需要把struct关键字和结构体名称一起作为类型名称使用。结构体变量分配了内存,他们可以用来记录数字。

typedef

typedef关键字可以用来给一个数据类型起别名,别名可以用来代替原有的类型名称,通常会给结构体类型起别名,可以把声明结构体的语句和起别名的语句合并成一条语句。这个时候可以省略结构体本省的名称。

声明结构体变量的时候也应该进行初始化,结构体变量初始化的方法和数组的初始化方法一样,结构体变量通常不能作为整体使用,一般一次只是用其中某个子存储区。以下写法可以用来表示结构体的某个子存储区。

/*
 *
 *结构体
 *
 * */
#include<stdio.h>
/*struct person{
		int age;
		float height;
		char name[10];
};
typedef struct person sperson;*/

typedef struct /*person*/{
	int age;
	float height;
	char name[10];
}sperson;
int main (){
	//struct person prsn; 		//结构体变量声明语句
	//sperson prsn1 = {18,48.3f,"abc"};
	printf("年龄是:%d\n",prsn1.age);
	printf("身高是:%g\n",prsn1.height);
	printf("名字是:%s\n",prsn1.name);
	return 0;
}

prsn.age

其中prsn是结构体变量名称,age是某个成员变量的名称。同类型结构体变量之间可以直接赋值,结构体指针用来记录结构体存储区的地址,以下写法可以通过结构体指针表示结构体的子存储区

p_person- >age

其中p_person是结构体指针,age是成员变量名称 。

posted @ 2024-10-30 19:35  GQH1000  阅读(16)  评论(0编辑  收藏  举报