2020.10.19 第18节 预处理和宏定义

本节详细讲解了C语言中的预处理概念,包括宏定义和宏函数的使用,以及#号的相关知识,同时涵盖了15和16节课的作业内容。
摘要由CSDN通过智能技术生成

2020.10.19 第18节 预处理和宏定义

一、宏定义和宏函数


	1.不需要; 不是一个语句
	2.宏定义 #define 
		2.1 宏替换
			常量: 窗口宽和高
			枚举类型: 多个常量 ,一类
			与typedef区别:
				typedef只能给类型起别名
				#define 可以替换东西
		2.2 宏函数
			短小精悍,常用的函数
		2.3 对编译器做一些处理
			
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <graphics.h>
#define MAX 100
#define WIDTH 800
#define HEIGHT 600
#define 如果 if
#define MAXNUM(a,b)  (a>b?a:b)
#define 主函数 int main(){
#define 函数结束 }
//宏函数的错误:学会分析
#define SUM(x) ((x)+(x))

主函数
	printf("%d\n", SUM(2) * 4); //2+2*4
	int  num;
	printf("%d", MAXNUM(1, 2));
	printf("%lf", MAXNUM(1.1, 2.3));
	initgraph(WIDTH, HEIGHT, 1);
	scanf("%d", &num);
	printf("%d", num);
	printf("Max=%d\n", MAX);
	如果(1)		//if(1)
	{
		printf("ILoveyou");
	}
	while (1);
	closegraph();
	return 0;
函数结束

二、#号知识

#include <stdio.h>
//#结合宏定义去做其他事情
#define CREATE(i)  value##i   //value1
#define CREATENAME(name,i) name##i
#define TOSTRING(str) #str   //C#  ToString unity
enum weeks {,,,,,,};
//宏定义
//多行宏定义
#define  STR if(a==1){printf("你好帅!\n");}else{printf("你不帅!\n");}
//宏定义
#define STR2 if(a==1)		\
		printf("你好帅\n");

//do_while(0)  避免替换语句和其他语句冲突

#define  CreateStruct(name,type)			\
	struct name{							\
		type data;                          \
		struct name* next;                  \
    }                                     

struct data
{
	char name[20];
	int age;
};


int main() 
{
	//int value1=12;
	int CREATE(1) = 12;
	printf("%d\n", value1);
	printf("%d\n", CREATE(1));
	for (int i = 0; i < 4; i++) 
	{
		int CREATENAME(name,i) = 1;
		printf("%d\t", CREATENAME(name, i));
	}
	printf("\n");
	int num = 11;
	printf("%s\n", TOSTRING(num));
	printf("%s\n", TOSTRING());
	int a = 1;
	STR;
	STR2;
	泛型编程  类型参数化
	CreateStruct(MM, int);
	CreateStruct(DATA, struct data);
	return 0;
}

三、预处理

#pragma once   //避免重复包含问题,避免头文件交叉包含造成重定义问题
#ifndef  _HEAD_H
#define _HEAD_H
struct MM 
{
	int data;
	struct MM* next;
};
#endif // ! _HEAD_H

#include <stdio.h>

	预处理
	<1>.编译器完成
		条件编译---->兼容性处理
		#if
		#else
		#elif

		#endif
		#ifndef
		#undef

#define NUM 1  //符号常量

int main() 
{
	int a = 1;
#if NUM==1
	printf("ILoveyou\n");
#else 
	printf("IMissyou\n");
#endif
#if 0
	printf("ILoveyou!\n");
#elif 2
	printf("ILoveyou\n");
#endif
#define MAX 100
	printf("Max=%d\n", MAX);
#undef MAX   //取消宏定义的使用
	//库中的遗留的宏定义
	printf("%s\n", __FILE__);
	printf("%s\n", __TIME__);
	printf("%s\n", __DATE__);
#pragma message("ILoveyou")
	return 0;
}

四、15课作业

//问题:滑行的情况 偶然会出现 
#include <graphics.h>
#include <time.h>
int map[4][6] = { 0 };  //撞击地图
struct board			//反弹板
{ 
	int x;
	int y;
	int width;
	int height;
};  
struct board myBoard = {200,775,200,25};//我的反弹板   全局变量
struct ball								//撞击球
{
	int x;
	int y;
	int r;
	int dx;
	int dy;
};					
struct ball myBall = { 300,400,10,5,8 };//我的撞击球   全局变量

void modifyMap()    //地图板与球相撞的消除
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 6; j++)
		{
			int x = 100 * j; //行 
			int y = 25 * i;  //列 砖块
			if (map[i][j] != -1)    //此块是否为空
			{
				if (x<myBall.x && x + 100>myBall.x)  //球在块的长 
				{
					if (myBall.y-myBall.r <= y + 25)   //撞板的下面  ,速度的关系
					{
						myBall.dy = -myBall.dy;		//球变向
						map[i][j] = -1;				//板子置空
					}
					if (myBall.y - myBall.r == y)   //撞板的上面?? 条件不够细  不然把上面的全消除了
					{
						myBall.dy = -myBall.dy;
						map[i][j] = -1;
					}
				}
				if (y<myBall.y && y + 25>myBall.y)  //球在块的高内 撞左右  侧面消除
				{
					if (myBall.x - myBall.r == x + 100)  //撞板的右面
					{
						myBall.dx = -myBall.dx;
						map[i][j] = -1;
					}
					else if (myBall.x - myBall.r == x)	//撞板的左面
					{
						myBall.dy = -myBall.dy;
						map[i][j] = -1;
					}
				}
			}
		}
	}
	//int j = myBall.x / 100;
	//int i = (myBall.y-myBall.r) / 25;
	//if (i < 4 && j < 6 && map[i][j] != -1)
	//{
	//	myBall.dy = -myBall.dy;
	//	map[i][j] = -1;		
	//}
	//与球上下左右四个方向相撞
}
void Ball(struct ball* myBall)   //撞击球的移动以及绘制
{
	solidcircle(myBall->x, myBall->y, myBall->r); //画球 圆心坐标,半径
	//球的移动  判断增量变化情况
	if (myBall->x <= myBall->r|| myBall->x >= 600 - myBall->r) 
	{
		myBall->dx = -myBall->dx;			//撞击左右墙后 x轴增量变为相反数
	}
	if (myBall->y <= myBall->r /*|| myBall->y >= 775 - myBall->r*/)
	{
		
		myBall->dy = -myBall->dy;			//撞击上墙后 y轴增量变为相反数
	}
	if (myBall->y >= myBoard.y - myBall->r)   
	{
		//如果小球要进入7大于775的范围   是否有反弹板子
		if (myBoard.x < myBall->x && myBoard.x + myBoard.width>myBall->x)
		{
			myBall->dy = -myBall->dy; //有反弹板子变向,没有就继续走,不反弹		
		}
	}
	// 进行移动
	myBall->x += myBall->dx;   //小球移动
	myBall->y += myBall->dy;
	Sleep(10);
} 

//游戏结束:1.球在地图外面 2.没有目标板
int gameOver()
{
	if (myBall.y >= 800 - myBall.r)
	{		
		return -50;    //球在地图外面,返回-50
	}	
	int result = 0;
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 6; j++)
		{
			switch (map[i][j])
			{
			case 0:case 1:case 2:case 3:
				result += 1;   //有目标板,result++   1-24
				break;
			case -1:
				result -=1; //没有目标板 
				break;
			}
		}
	}
	return result;
}

void initMap()	//地图的随机生成
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 6; j++)
		{
			map[i][j] = rand() % 4;						
		}
	}
}   
void drawMap()  //撞击地图的绘制
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 6; j++)
		{
			int x = 100 * j;
			int y = 25 * i;
			setlinecolor(BLACK);
			switch (map[i][j])
			{				
			case 0:
				setfillcolor(RED);
				fillrectangle(x, y, x + 100, y + 25);
				break;
			case 1:
				setfillcolor(YELLOW);
				fillrectangle(x, y, x + 100, y + 25);
				break;
			case 2:
				setfillcolor(BLUE);
				fillrectangle(x, y, x + 100, y + 25);
				break;
			case 3:
				setfillcolor(MAGENTA);
				fillrectangle(x, y, x + 100, y + 25);
				break;
			}
		}
	}
}

void drawBoard()		//反弹板的绘制
{
	setfillcolor(WHITE);
	fillrectangle(myBoard.x, myBoard.y, myBoard.x + 200,
	myBoard.y + 25);
}
void moveBoard()  //反弹板的移动
{
	if (GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT))
	{
		if (myBoard.x > 0)
			myBoard.x -= 25;
		else
			myBoard.x = 0;
	}
	if (GetAsyncKeyState('D') || GetAsyncKeyState (VK_RIGHT))
	{
		if (myBoard.x < 600 - myBoard.width)
			myBoard.x += 25;
		else
			myBoard.x = 600 - myBoard.width;
	}

}

int main()
{
	struct ball* tempBall = &myBall;	
	srand((unsigned int)time(0));
	initMap();
	initgraph(600, 800);
	while (1)
	{
		BeginBatchDraw();
		cleardevice();		//按键移动后清屏 打印新的位置 形成动画
		drawMap();
		drawBoard();
		if (gameOver() == -50)  //移动反弹版之前 看是否游戏结束
		{
			settextcolor(RED);
			settextstyle(50, 0, "楷体");
			outtextxy(100, 250, "游戏结束,失败!");			
			EndBatchDraw();
			while (1);		
			closegraph();  //关闭窗口
			return 0;
		}
		if (gameOver() == -24)
		{
			settextcolor(RED);
			settextstyle(50, 0, "楷体");
			outtextxy(100, 250, "游戏结束,成功!");
			EndBatchDraw();
			while (1);
			closegraph();
			return 0;
		}
		Ball(tempBall);
		moveBoard();


		modifyMap();
		EndBatchDraw();
	}

	
	while (1);
	closegraph();
	return 0;
}

五、16课作业

/*
	链表: 充当数据的容器
		可以灵活存取数据
	//管理系统
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct MM 
{
	char name[20];
	int age;
	int num;
	char addr[20];
};

struct Node
{
	//int data;
	struct MM data;
	struct Node* next;
};
struct Node* list = NULL;
int curSize = 0;

struct Node* createHead()
{
	//1.动态内存申请
	struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
	//(*headNode).next = NULL;
	headNode->next = NULL;
	return headNode;
}
struct Node* createNode(struct MM  data)
{
	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
	newNode->data = data;
	newNode->next = NULL;  //作为链表结束标志
	return newNode;
}

void insertByHead(struct Node* headNode, struct MM data)
{
	struct Node* newNode = createNode(data);	//调用自己写的函数
	//下面两句先后顺序不能交换
	//先连后断
	newNode->next = headNode->next;
	headNode->next = newNode;
	curSize++;
}
//8.指定位置删除
void deleteByName(struct Node* headNode, char *mmName)
{
	struct Node* frontNode = headNode;
	struct Node* posNode = headNode->next;
	while (posNode != NULL && strcmp(posNode->data.name , mmName))
	{
		frontNode = posNode;
		posNode = frontNode->next;
	}
	if (posNode == NULL)
	{
		printf("未找到,无法删除!\n");
	}
	else
	{
		frontNode->next = posNode->next;
		free(posNode);
		curSize--;
		posNode = NULL;
	}

}

struct Node* searchByName(struct Node* headNode, char* mmName) 
{
	struct Node* pMove = headNode->next;
	while (pMove != NULL && strcmp(pMove->data.name, mmName)) 
	{
		pMove = pMove->next;
	}
	return pMove;
}

//9.遍历--->打印
void printList(struct Node* headNode)
{
	//为什么指向第二个节点? 因为第一个节点没有存数据
	struct Node* pMove = headNode->next;
	//表头
	printf("姓名\t年龄\t编号\t地址\n");
	while (pMove != NULL)
	{
		//printf("%d\t", pMove->data);
		printf("%s\t%d\t%d\t%s\n", pMove->data.name, pMove->data.age, pMove->data.num, pMove->data.addr);
		pMove = pMove->next;
	}
	printf("\n");
}
void sortArray(int array[], int arrayNum)
{
	for (int i = 0; i < arrayNum - 1; i++)
	{
		for (int j = 0; j < arrayNum - i - 1; j++)
		{
			if (array[j] > array[j + 1])
			{
				int temp = array[j];
				array[j] = array[j + 1];
				array[j + 1] = temp;
			}
		}
	}
}
void sortList(struct Node* headNode) 
{
	if (headNode == NULL)
		return;
	for (struct Node* pFirst = headNode->next; pFirst != NULL&&pFirst->next!=NULL; pFirst = pFirst->next) 
	{
		for (struct Node* pSecond = headNode->next; pSecond->next!=NULL; pSecond = pSecond->next) 
		{
			if (strcmp(pSecond->data.name, pSecond->next->data.name) > 0) 
			{
				struct MM tempMM = pSecond->data;
				pSecond->data = pSecond->next->data;
				pSecond->next->data = tempMM;
			}
		}
	}
}
void  readInfoFromFile(struct Node* headNode, const char* fileName) 
{
	FILE* fp = fopen(fileName, "r");
	if (fp == NULL) 
	{
		fp = fopen(fileName, "w+");
		fclose(fp);
		return;
	}
	struct MM tempData;  //struct Node data;
	while (fscanf(fp, "%s\t%d\t%d\t%s\n", tempData.name, &tempData.age, &tempData.num, tempData.addr) != EOF) 
	{
		insertByHead(headNode, tempData);
	}
	fclose(fp);
}
void saveInfoToFile(struct Node* headNode, const char* fileName) 
{
	FILE* fp = fopen(fileName, "w");  //清空原来的数据
	struct Node* pMove = headNode->next;
	while (pMove) 
	{
		fprintf(fp, "%s\t%d\t%d\t%s\n", pMove->data.name, pMove->data.age, pMove->data.num, pMove->data.addr);
		pMove = pMove->next;
	}
	fclose(fp);
}


void makeMenu() 
{
	printf("------------MM 管理系统 ---------\n");
	printf("\t\t0.退出系统\n");
	printf("\t\t1.录入系统\n");
	printf("\t\t2.浏览信息\n");
	printf("\t\t3.删除信息\n");
	printf("\t\t4.修改信息\n");
	printf("\t\t5.查找信息\n");
	printf("\t\t6.排序信息\n");
	printf("-----------------------------------\n");
}
void keyDown() 
{
	int userKey = 0;
	struct MM tempData;
	struct Node* result = NULL;
	scanf("%d", &userKey);
	switch (userKey) 
	{
	case 0:
		printf("正常退出!\n");
		system("pause");
		exit(0);
		break;
	case 1:
		printf("name,age,num,addr:");
		scanf("%s%d%d%s", tempData.name, &tempData.age, &tempData.num, tempData.addr);
		insertByHead(list, tempData);
		saveInfoToFile(list, "mm.txt");
		break;
	case 2:
		printList(list);
		break;
	case 3:
		printf("input Name:");
		scanf("%s", tempData.name);
		deleteByName(list, tempData.name);
		saveInfoToFile(list, "mm.txt");
		break;
	case 4:
		printf("input Name:");
		scanf("%s", tempData.name);
		result = searchByName(list, tempData.name);
		if (result == NULL)
		{
			printf("未找到\n");
		}
		else
		{
			printf("input new name,age,num,addr:");
			scanf("%s%d%d%s", result->data.name, &result->data.age, &result->data.num, result->data.addr);
		}
		break;
	case 5:
		printf("input Name:");
		scanf("%s", tempData.name);
		result = searchByName(list, tempData.name);
		if (result == NULL) 
		{
			printf("未找到\n");
		}
		else 
		{
			printf("姓名\t年龄\t编号\t地址\n");
			printf("%s\t%d\t%d\t%s\n", result->data.name, result->data.age, result->data.num, result->data.addr);
			saveInfoToFile(list, "mm.txt");
		}
		break;
	case 6:
		sortList(list);
		printList(list);
		break;
	default:
		printf("请重新输入!\n");
		break;
	}
}
int main()
{
	list = createHead();
	readInfoFromFile(list, "mm.txt");
	while (1) 
	{
		makeMenu();
		keyDown();
		system("pause");
		system("cls");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值