C语言学习笔记之 主函数、预处理与注释

Hello world

代码:

#include <stdio.h> // 标准(std)输入(i:input)输出(o:output)
#include <stdlib.h>

int main(int argc. char *argv[]) {
    printf("Hello world
");
    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
", argc);
	for (int i = 0; i < argc; i++) {
		printf("%s ", argv[i]);
	}
	printf("
");
	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
",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
");
	#endif
	#ifdef __linux__
	printf("Linux
");
	#endif

	printf("__FILE__:%s
", __FILE__);
	printf("__LINE__:%s
", __LINE__);
	printf("__DATE__:%s
", __DATE__);
	printf("__TIME__:%s
", __TIME__);
	printf("__func__:%s
", __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
");
}
#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
");
	return 0;
}
#endif

该程序在Windows下编译的结果:

#pragma

  1. pragma once

    在头文件最开头加上这一句可以防止头文件重复引用

  2. pragma message()

    编译时编译器会显示message里的内容,并继续编译
    如:

    #pragma message("Hello world")
    #include <stdio.h>
    
    int main() {
    	printf("Hello C
    ");
    	return 0;
    }
    

    运行结果:

  3. pragma warning

    #pragma warning(disable:4707) // 屏蔽4707警告
    
    #pragma warning(once:4707) // 只显示一次4707警告
    
    #pragma warning(error:164) // 将164号警告当成一个错误
    
  4. pragma comment(lib,"库文件路径")

    该指令用于导入库

    #pragma comment(lib,"D:/lib/libmy_lib.lib") // 将my_lib.lib导入项目
    
  5. pargma pack(n)

    用于内存对齐

原文地址:https://www.cnblogs.com/zhujiangyu/p/13583414.html