C语言学习笔记之 主函数、预处理与注释
Hello world
代码:
#include <stdio.h> // 标准(std)输入(i:input)输出(o:output)
#include <stdlib.h>
int main(int argc. char *argv[]) {
printf("Hello world\n");
system("pause");
return 0;
}
运行结果:
Hello world
详解
预处理
include 文件包含命令
作用:导入对应的头文件(.h)
语法:
#include <头文件.h>
#include "头文件.h"
- 使用尖括号<>,编译器会到系统路径下查找头文件
- 使用双引号"",编译器首先在当前目录下查找头文件,如果没有找到,再到系统路径下查找
注意事项
- 一个 #include 命令只能包含一个头文件,多个头文件需要多个 #include 命令
- 同一个头文件可以被多次引入,多次引入的效果和一次引入的效果相同,因为头文件在代码层面有防止重复引入的机制
- 文件包含允许嵌套,也就是说在一个被包含的文件中又可以包含另一个文件
主函数
一个项目有且仅有一个主函数
当运行可执行文件的时候,系统会自动调用主函数
参数
- argc
可执行文件接收的参数数量
- argv
参数列表,其中第一个参数是可执行文件的文件名
实例:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("argc:%d\n", argc);
for (int i = 0; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
return 0;
}
编译:
gcc main.c -o main
运行:
./main a b c
运行结果:
argc:4
D:\main.exe a b c
注释
注释在编译后不会被留在可执行文件中
行注释
// 注释内容
块注释
/*
注释内容
注释内容
*/
注意!块注释尽量不要嵌套!
预处理
#include 文件包含命令
略
#define 宏定义
一般形式:
#define 宏名 字符序列
这里的字符序列不是字符串,字符序列可以是数字、字符串("ab")、字符('a')、表达式、函数等
编译器在预处理时,会把所有的宏名替换为对应的字符序列
比如定义了一个宏#define PI 3.14
此时有一条语句:
printf("PI = %.2f",PI);
那么在预处理时会把PI换成3.14,而字符串中的PI不会替换
printf("PI = %.2f",3.14); // 替换后的结果
注意!#define只会无脑替换
带参数的宏
一般形式:
#define 宏名(参数列表) 表达式
实例:
#include <stdio.h>
#define MAX(x,y) (x>y) ? x : b
int main() {
int a,b,max;
printf("请输入两个数:");
scanf("%d %d",&a,&b);
max = MAX(a,b);
printf("max = %d\n",max);
return 0;
}
运行结果:
请输入两个数:1,3
max = 3
因为宏是无脑替换,所以参数不需要写数据类型,
且宏不占用内存
C语言预定义的宏
宏 | 含义 |
---|---|
_WIN32 | 代表Windows平台 |
__linux__ | 代表Linux平台 |
__DATE__ | 进行预处理的日期 |
__FILE__ | 当前源文件名的字符串文字 |
__TIME__ | 源文件编译的时间 |
__func__ | 当前所在的函数名 |
__LINE__ | 当前源代码的行数 |
测试代码:
// main.c
#include <stdio.h>
int main() {
#ifdef _WIN32
printf("Windows\n");
#endif
#ifdef __linux__
printf("Linux\n");
#endif
printf("__FILE__:%s\n", __FILE__);
printf("__LINE__:%s\n", __LINE__);
printf("__DATE__:%s\n", __DATE__);
printf("__TIME__:%s\n", __TIME__);
printf("__func__:%s\n", __func__);
return 0;
}
Windows运行结果:
Windows
__FILE__:main.c
__LINE__:13
__DATE__:Aug 30 2020
__TIME__:20:39:16
__func__:main
条件编译
#if #elif #endif #ifdef #ifndef
#if 的用法
#if 整型常量表达式1 // 开始
程序段1
#elif 整型常量表达式2
程序段2
#else
程序段3
#endif // 结束
上面的代码表示:如果整型常量表达式1的值非0,那么编译程序段1,如果整型常量表达式1的值为0,且整型常量表达式2的值非0,那么编译程序段2,否则编译程序段3,#endif 表示结束
#ifdef 的用法
#ifdef 宏名
程序段1
#else
程序段2
#endif
上面的代码表示如果当前的宏被定义过,则对程序段1进行编译,否则编译程序段2
ifdef 相当于 #if defined的缩写
例:
#if defined(_WIN32)
#include <stdio.h>
int main() {
printf("Hello windows\n");
}
#endif
Windows运行结果:
Hello windows
#ifndef
#ifndef 宏名
程序段1
#else
程序段2
#endif
上面的代码表示如果当前的宏没有被定义过,则对程序段1进行编译,否则编译程序段2
#error
编译程序时,只要遇到#error,就会生成一个编译错误提示,并停止编译
#error [错误信息] // []表示可选
例:
#ifndef __linux__
#error "你现在的平台不是Linux平台"
#else
#include <stdio.h>
int main() {
printf("Hello Linux\n");
return 0;
}
#endif
该程序在Windows下编译的结果:
#pragma
-
pragma once
在头文件最开头加上这一句可以防止头文件重复引用
-
pragma message()
编译时编译器会显示message里的内容,并继续编译
如:#pragma message("Hello world") #include <stdio.h> int main() { printf("Hello C\n"); return 0; }
运行结果:
-
pragma warning
#pragma warning(disable:4707) // 屏蔽4707警告 #pragma warning(once:4707) // 只显示一次4707警告 #pragma warning(error:164) // 将164号警告当成一个错误
-
pragma comment(lib,"库文件路径")
该指令用于导入库
#pragma comment(lib,"D:/lib/libmy_lib.lib") // 将my_lib.lib导入项目
-
pargma pack(n)
用于内存对齐