预处理和宏定义
宏不是语句,所以宏后面没有分号
替换后的语法依旧需要满足C语言的语法
#define
宏替换
- 宏替换就是单纯的替换
#define 整数 int
#define A a+b
#define B (a+b)
int iNum = 0;
整数 iNum2 = 0; //int iNum2 = 0;
int a = 1;
int b = 2;
int result = A; //int result=a+b;
printf("%d\n", result); //3
result = 3 * A; //错误解析:3*(a+b);
printf("%d\n", result); //宏替换就是单纯的的替换 3*1+2
result = 3 * B;
printf("%d\n", result);
宏函数
-
可以忽略类型的一种通用性函数
-
不是宏函数,不需要算出表达式,如果是宏函数,先算里面的表达式
#define MAX(a,b) ((a)>(b)?(a):(b)) #define SWAP(a,b) {int temp=(a),(a)=(b),(b)=temp;} #define M 2 #define SUM(M) M+M #define SUM2(M) ((M)+(M)) printf("%d\n", MAX(1, 2)); printf("%lf\n", MAX(1.1, 2.2)); printf("%C\n", MAX('A', 'B')); SWAP(a, b); printf("a=%d\tb=%d\n", a, b); result = SUM(4); printf("%d\n", result); result = SUM(M); printf("%d\n", result); result = SUM(M) * 2; //2+2*2 printf("%d\n", result); result = SUM(1+2) * 2; //3+3*2=9 1+2+1+2*2=8 printf("%d\n", result); result = SUM2(1 + 2) * 2; printf("%d\n", result);
宏语句(多行写法)
- 用\做连接
define isOS(x) do{ \
if ((x) % 2 == 0) \
printf("偶数\n"); \
else \
printf("奇数\n"); \
}while (0)
int x = 100;
isOS(x);
条件编译
-
必须和#endif 结合使用
-
条件编译基本用法,和if和else 差不多
-
使用方式和正常的if_else 差不多,只是写法上稍微不同
-
条件编译是在程序运行前完成的
#if 1 printf("条件编译\n"); #else printf("条件不成立,不做编译"); #endif #if 1 printf("if\n"); #elif 2 //等效else if printf("elif\n"); #elif 3 printf("elif\n"); #else printf("else\n"); #endif
条件编译——条件宏
-
条件编译是在程序运行前完成的
-
一般充当条件编译的条件是全局变量,或者是宏
#define NUM 1 int a = 1; #if a>0 printf("a>0\n"); #else printf("a<0\n"); #endif #if NUM>0 printf("NUM>0\n"); #else printf("NUM<0\n"); #endif
宏替换做条件编译
-
#ifndef 判定宏不存在
-
#ifdef 判定宏存在
-
#undef 取消宏定义的作用域
#ifdef NUM #define NUM2 100 #endif printf("%d\n", NUM2); #ifndef NUM #define NUM 200 #endif #define MAX 200 printf("%d\n", MAX); #undef MAX
特殊命令
-
#直接转字符串
#define toString(str) #str
-
##连接符
#define catName(num) name##num //产生的是一个新的变量名
-
#pragma
-
warning
-
去掉提醒
-
让编译器忽略提示
#pragma warning(disable:4996) #pragma warning(disable:6031)
-
-
-
comment
-
包含第三方静态、动态库
#pragma comment(lib,"winmm.lib")
-
-
pack
-
强制设置对齐方式 1 2 4 8 整数倍
#pragma pack(1) //1 2 4 8 struct student { char name[7]; int num; };
-
-
特殊宏
printf("%s\n", __FILE__);
printf("%s\n", __DATE__);
printf("%s\n", __TIME__);
printf("%d\n", __LINE__);
多文件
-
允许多个.c文件和.h文件
-
一个项目可以有多个文件,但是只能有一个入口函数
-
extern 声明外部变量
-
一个.h文件对应一个.c文件
-
.h只写声明
-
尽量避免头文件嵌套
testHead.h文件 #pragma once int testHead; testHead.c文件 #include "testHead.h" testHead = 0;
结构体的多文件写法
node.h
#pragma once
#ifndef __NODE__H
#define __NODE__H
#include <stdio.h>
#include <stdlib.h>
//结构体声明
typedef struct Node
{
int data;
struct Node* next;
}NODE,*LPNODE,*LPLIST;
//函数声明
LPLIST createList();
LPNODE createNode(int data);
void insertByHead(LPLIST list, int dta);
void printList(LPLIST list);
#endif
node.c
#include "node.h"
LPLIST createList()
{
LPNODE headNode = (LPNODE)malloc(sizeof(NODE));
return headNode;
}
LPNODE createNode(int data)
{
LPNODE headNode = (LPNODE)malloc(sizeof(NODE));
return headNode;
}
void insertByHead(LPLIST list, int dta)
{
printf("插入\n");
}
void printList(LPLIST list)
{
printf("打印!\n");
}
命令行程序
-
argc:命令行个数的
-
argv[0]: 记录当前exe文件的路径(exe的名字)
-
argv[1]: 第二个命令
int main(int argc,char *argv[]) { if (argc != 3) { printf("指令异常!\n"); printf("%s\n", argv[0]); } else { for (int i = 0; i < 3; i++) { printf("%s\n", argv[i]); } } return 0; }
命令行程序运行方式
- 打开cmd,进入到exe文件路径
- 然后输入指令