【C语言技能树】程序环境和预处理
Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法......感兴趣就关注我吧!你定不会失望。
🌈个人主页:主页链接
🌈算法专栏:专栏链接
我会一直往里填充内容哒!
🌈LeetCode专栏:专栏链接
目前在刷初级算法的LeetBook 。若每日一题当中有力所能及的题目,也会当天做完发出
🌈代码仓库:Gitee链接
🌈点击关注=收获更多优质内容🌈
目录
1. 程序的翻译环境和执行环境:
2. 详解编译+链接
2.1翻译环境
2.2 编译本身也分为几个阶段 预编译,编译与处理.
2.21预编译
2.22编译
2.23汇编阶段
2.3链接
3. 预处理详解
3.1 预定义符号
3.2 #define
3.2.1#define 定义宏
3.2.2 #define 替换规则
3.2.3 #和##
3.2.4 宏和函数对比
3.2.7 命名约定
3.3 #undef
3.4 命令行定义
3.5 文件包含
完结撒花:
1. 程序的翻译环境和执行环境:
在ANSI C的任何一种实现中,存在两个不同的环境。
第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。
第2种是执行环境,它用于实际执行代码
在计算机当中,只能执行二进制编码,那我们的编程语言又是如何转换成二进制编码的呢?
以我们常用的vs为例,这是一个集成开发环境,从.c到.exe都可以由他来完成.

经过编译与链接这两个大步骤,就可以生成可执行程序.
2. 详解编译+链接
2.1翻译环境

组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。
每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序中
2.2 编译本身也分为几个阶段 预编译,编译与处理.
2.21预编译
预处理阶段会将预处理指令进行替换
如下的#include 与 #define都是预处理指令。
#include<stdio.h>
#define MAX 5
int main()
{printf("%d",MAX);return 0;
//预处理
}
使用gcc执行:gcc -E test.c -o test.i 可在预处理后停下.这时预处理指令替换完成
define定义的常量进行文本替换 include所包含的头文件被展开,注释将被删除
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "test.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 1 3 4
# 33 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 461 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
# 452 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 453 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/long-double.h" 1 3 4
# 454 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 462 "/usr/include/features.h" 2 3 4
# 485 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
# 486 "/usr/include/features.h" 2 3 4
# 34 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4# 1 "/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h" 1 3 4
# 209 "/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h" 3 4# 209 "/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h" 3 4
typedef long unsigned int size_t;
# 34 "/usr/include/stdio.h" 2 3 4# 1 "/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h" 1 3 4
# 40 "/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 37 "/usr/include/stdio.h" 2 3 4# 1 "/usr/include/x86_64-linux-gnu/bits/types.h" 1 3 4
# 27 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 28 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 1 3 4
# 29 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;typedef __int8_t __int_least8_t;
typedef __uint8_t __uint_least8_t;
typedef __int16_t __int_least16_t;
typedef __uint16_t __uint_least16_t;
typedef __int32_t __int_least32_t;
typedef __uint32_t __uint_least32_t;
typedef __int64_t __int_least64_t;
typedef __uint64_t __uint_least64_t;typedef long int __quad_t;
typedef unsigned long int __u_quad_t;typedef long int __intmax_t;
typedef unsigned long int __uintmax_t;
# 141 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/typesizes.h" 1 3 4
# 142 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/time64.h" 1 3 4
# 143 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4typedef unsigned long int __dev_t;
typedef unsigned int __uid_t;
typedef unsigned int __gid_t;
typedef unsigned long int __ino_t;
typedef unsigned long int __ino64_t;
typedef unsigned int __mode_t;
typedef unsigned long int __nlink_t;
typedef long int __off_t;
typedef long int __off64_t;
typedef int __pid_t;
typedef struct { int __val[2]; } __fsid_t;
typedef long int __clock_t;
typedef unsigned long int __rlim_t;
typedef unsigned long int __rlim64_t;
typedef unsigned int __id_t;
typedef long int __time_t;
typedef unsigned int __useconds_t;
typedef long int __suseconds_t;typedef int __daddr_t;
typedef int __key_t;typedef int __clockid_t;typedef void * __timer_t;typedef long int __blksize_t;typedef long int __blkcnt_t;
typedef long int __blkcnt64_t;typedef unsigned long int __fsblkcnt_t;
typedef unsigned long int __fsblkcnt64_t;typedef unsigned long int __fsfilcnt_t;
typedef unsigned long int __fsfilcnt64_t;typedef long int __fsword_t;typedef long int __ssize_t;typedef long int __syscall_slong_t;typedef unsigned long int __syscall_ulong_t;typedef __off64_t __loff_t;
typedef char *__caddr_t;typedef long int __intptr_t;typedef unsigned int __socklen_t;typedef int __sig_atomic_t;
# 39 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h" 1 3 4# 1 "/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h" 1 3 4
# 13 "/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h" 3 4
typedef struct
{int __count;union{unsigned int __wch;char __wchb[4];} __value;
} __mbstate_t;
# 6 "/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h" 2 3 4typedef struct _G_fpos_t
{__off_t __pos;__mbstate_t __state;
} __fpos_t;
# 40 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h" 3 4
typedef struct _G_fpos64_t
{__off64_t __pos;__mbstate_t __state;
} __fpos64_t;
# 41 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/__FILE.h" 1 3 4struct _IO_FILE;
typedef struct _IO_FILE __FILE;
# 42 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/FILE.h" 1 3 4struct _IO_FILE;typedef struct _IO_FILE FILE;
# 43 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h" 1 3 4
# 35 "/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h" 3 4
struct _IO_FILE;
struct _IO_marker;
struct _IO_codecvt;
struct _IO_wide_data;typedef void _IO_lock_t;struct _IO_FILE
{int _flags;char *_IO_read_ptr;char *_IO_read_end;char *_IO_read_base;char *_IO_write_base;char *_IO_write_ptr;char *_IO_write_end;char *_IO_buf_base;char *_IO_buf_end;char *_IO_save_base;char *_IO_backup_base;char *_IO_save_end;struct _IO_marker *_markers;struct _IO_FILE *_chain;int _fileno;int _flags2;__off_t _old_offset;unsigned short _cur_column;signed char _vtable_offset;char _shortbuf[1];_IO_lock_t *_lock;__off64_t _offset;struct _IO_codecvt *_codecvt;struct _IO_wide_data *_wide_data;struct _IO_FILE *_freeres_list;void *_freeres_buf;size_t __pad5;int _mode;char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
};
# 44 "/usr/include/stdio.h" 2 3 4
# 52 "/usr/include/stdio.h" 3 4
typedef __gnuc_va_list va_list;
# 63 "/usr/include/stdio.h" 3 4
typedef __off_t off_t;
# 77 "/usr/include/stdio.h" 3 4
typedef __ssize_t ssize_t;typedef __fpos_t fpos_t;
# 133 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/stdio_lim.h" 1 3 4
# 134 "/usr/include/stdio.h" 2 3 4extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__));extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__));extern int renameat (int __oldfd, const char *__old, int __newfd,const char *__new) __attribute__ ((__nothrow__ , __leaf__));
# 173 "/usr/include/stdio.h" 3 4
extern FILE *tmpfile (void) ;
# 187 "/usr/include/stdio.h" 3 4
extern char *tmpnam (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;extern char *tmpnam_r (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;
# 204 "/usr/include/stdio.h" 3 4
extern char *tempnam (const char *__dir, const char *__pfx)__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ;extern int fclose (FILE *__stream);extern int fflush (FILE *__stream);
# 227 "/usr/include/stdio.h" 3 4
extern int fflush_unlocked (FILE *__stream);
# 246 "/usr/include/stdio.h" 3 4
extern FILE *fopen (const char *__restrict __filename,const char *__restrict __modes) ;extern FILE *freopen (const char *__restrict __filename,const char *__restrict __modes,FILE *__restrict __stream) ;
# 279 "/usr/include/stdio.h" 3 4
extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) ;
# 292 "/usr/include/stdio.h" 3 4
extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)__attribute__ ((__nothrow__ , __leaf__)) ;extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) ;extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__));extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__));extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf,size_t __size) __attribute__ ((__nothrow__ , __leaf__));extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));extern int fprintf (FILE *__restrict __stream,const char *__restrict __format, ...);extern int printf (const char *__restrict __format, ...);extern int sprintf (char *__restrict __s,const char *__restrict __format, ...) __attribute__ ((__nothrow__));extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,__gnuc_va_list __arg);extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg);extern int vsprintf (char *__restrict __s, const char *__restrict __format,__gnuc_va_list __arg) __attribute__ ((__nothrow__));extern int snprintf (char *__restrict __s, size_t __maxlen,const char *__restrict __format, ...)__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4)));extern int vsnprintf (char *__restrict __s, size_t __maxlen,const char *__restrict __format, __gnuc_va_list __arg)__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0)));
# 379 "/usr/include/stdio.h" 3 4
extern int vdprintf (int __fd, const char *__restrict __fmt,__gnuc_va_list __arg)__attribute__ ((__format__ (__printf__, 2, 0)));
extern int dprintf (int __fd, const char *__restrict __fmt, ...)__attribute__ ((__format__ (__printf__, 2, 3)));extern int fscanf (FILE *__restrict __stream,const char *__restrict __format, ...) ;extern int scanf (const char *__restrict __format, ...) ;extern int sscanf (const char *__restrict __s,const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf");
extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf");
extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__));
# 432 "/usr/include/stdio.h" 3 4
extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,__gnuc_va_list __arg)__attribute__ ((__format__ (__scanf__, 2, 0))) ;extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg)__attribute__ ((__format__ (__scanf__, 1, 0))) ;extern int vsscanf (const char *__restrict __s,const char *__restrict __format, __gnuc_va_list __arg)__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0)));extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf")__attribute__ ((__format__ (__scanf__, 2, 0))) ;
extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf")__attribute__ ((__format__ (__scanf__, 1, 0))) ;
extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__))__attribute__ ((__format__ (__scanf__, 2, 0)));
# 485 "/usr/include/stdio.h" 3 4
extern int fgetc (FILE *__stream);
extern int getc (FILE *__stream);extern int getchar (void);extern int getc_unlocked (FILE *__stream);
extern int getchar_unlocked (void);
# 510 "/usr/include/stdio.h" 3 4
extern int fgetc_unlocked (FILE *__stream);
# 521 "/usr/include/stdio.h" 3 4
extern int fputc (int __c, FILE *__stream);
extern int putc (int __c, FILE *__stream);extern int putchar (int __c);
# 537 "/usr/include/stdio.h" 3 4
extern int fputc_unlocked (int __c, FILE *__stream);extern int putc_unlocked (int __c, FILE *__stream);
extern int putchar_unlocked (int __c);extern int getw (FILE *__stream);extern int putw (int __w, FILE *__stream);extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream);
# 603 "/usr/include/stdio.h" 3 4
extern __ssize_t __getdelim (char **__restrict __lineptr,size_t *__restrict __n, int __delimiter,FILE *__restrict __stream) ;
extern __ssize_t getdelim (char **__restrict __lineptr,size_t *__restrict __n, int __delimiter,FILE *__restrict __stream) ;extern __ssize_t getline (char **__restrict __lineptr,size_t *__restrict __n,FILE *__restrict __stream) ;extern int fputs (const char *__restrict __s, FILE *__restrict __stream);extern int puts (const char *__s);extern int ungetc (int __c, FILE *__stream);extern size_t fread (void *__restrict __ptr, size_t __size,size_t __n, FILE *__restrict __stream) ;extern size_t fwrite (const void *__restrict __ptr, size_t __size,size_t __n, FILE *__restrict __s);
# 673 "/usr/include/stdio.h" 3 4
extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,size_t __n, FILE *__restrict __stream) ;
extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,size_t __n, FILE *__restrict __stream);extern int fseek (FILE *__stream, long int __off, int __whence);extern long int ftell (FILE *__stream) ;extern void rewind (FILE *__stream);
# 707 "/usr/include/stdio.h" 3 4
extern int fseeko (FILE *__stream, __off_t __off, int __whence);extern __off_t ftello (FILE *__stream) ;
# 731 "/usr/include/stdio.h" 3 4
extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos);extern int fsetpos (FILE *__stream, const fpos_t *__pos);
# 757 "/usr/include/stdio.h" 3 4
extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;extern void perror (const char *__s);# 1 "/usr/include/x86_64-linux-gnu/bits/sys_errlist.h" 1 3 4
# 26 "/usr/include/x86_64-linux-gnu/bits/sys_errlist.h" 3 4
extern int sys_nerr;
extern const char *const sys_errlist[];
# 782 "/usr/include/stdio.h" 2 3 4extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
# 800 "/usr/include/stdio.h" 3 4
extern FILE *popen (const char *__command, const char *__modes) ;extern int pclose (FILE *__stream);extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
# 840 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 858 "/usr/include/stdio.h" 3 4
extern int __uflow (FILE *);
extern int __overflow (FILE *, int);
# 873 "/usr/include/stdio.h" 3 4# 2 "test.c" 2# 3 "test.c"
int main()
{printf("%d",5);return 0;
}
2.22编译
在编译阶段会将c代码全部翻译为汇编代码 并进行 词法分析 语义分析 语法分析 符号汇总等工作
同样在gcc中执行:gcc -S test.i -o test.s
.file "test.c".text.section .rodata
.LC0:.string "%d".text.globl main.type main, @function
main:
.LFB0:.cfi_startprocendbr64pushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6movl $5, %esileaq .LC0(%rip), %rdimovl $0, %eaxcall printf@PLTmovl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size main, .-main.ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0".section .note.GNU-stack,"",@progbits.section .note.gnu.property,"a".align 8.long 1f - 0f.long 4f - 1f.long 5
0:.string "GNU"
1:.align 8.long 0xc0000002.long 3f - 2f
2:.long 0x3
3:.align 8
4:
刚刚的代码就被翻译成了汇编代码。并完成了上述过程。
其中符号汇总将使用到的各个函数与全局变量汇总
2.23汇编阶段
在编译中最后的阶段是汇编,将文件生成为目标文件,将汇编代码翻译成二进制代码,并整合刚刚的符号汇总生成符号表,并附上地址,以便之后调用。
同样在gcc中执行:gcc -C test.s -o test.o
就生成了这样一个乱码文件(可使用elf格式进行编辑)
2.3链接
最后就是链接阶段,合并段表,并执行符号表的合并与重定位。
当多文件操作的时候,这部会将多个文件进行链接操作。(也可以理解为将多个文件合并为一个文件)
在gcc中执行 gcc test.o -o test
就会生成一个可执行程序。
3. 预处理详解
3.1 预定义符号
__FILE__
//进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
#include<stdio.h>
#define MAX 5
int main()
{printf(__FILE__);printf(__FUNCTION__);printf(__TIME__);
}
执行结果如下。分别为文件名 函数名 时间
3.2 #define
#define name stuff
语法为要定义的名字 与 具体的值
如
#define MAX 5
如果定义的 stuff过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
date:%s\ttime:%s\n" ,\
__FILE__,__LINE__ ,\
__DATE__,__TIME__ )
在define定义中不要加;
来看看这段代码,当条件成立时a=max否则b=max
#define MAX 5;
if truea=MAX;
elseb=MAX;
但是在预编译处理阶段会将这段代码翻译成这样,也就将else孤立了,会导致语法错误
#define MAX 5;
if truea=MAX;;
elseb=MAX;;
所以在define中不需要加入;
3.2.1#define 定义宏
#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。
下面是宏的申明方式:
#define name( parament-list ) stuff
其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中。
#define max(x,y) ((x>y)?x:y)
参数列表的左括号必须与name紧邻。 如果两者中有空白的部分,则会被解释为stuff。
写宏时不要吝啬括号,否则会出现不好的结果
例如:定义平方和的宏
#define SQUARE( x ) x * x
int a = 5;
printf("%d\n" ,SQUARE( a + 1) );
在预编译结束后这段代码会变成什么呢?
#define SQUARE( a+1 ) a+1 * a+1
int a = 5;
printf("%d\n" ,a+1 * a+1 );
这时,显然结果改变了,所以我们应当这样定义宏
#define SQUARE( x ) ((x) * (x))
int a = 5;
printf("%d\n" ,SQUARE( a + 1) );
3.2.2 #define 替换规则
在程序中扩展#define定义符号和宏时,需要涉及几个步骤。
1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先
被替换。
2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。
3. 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上
述处理过程。
注意:
1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。
2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
3.2.3 #和##
#的作用是将变量名插入到字符串中
#include<stdio.h>
#define PRINTF(format,x) printf("the value of " #x " is " format "\n",x)
int main()
{int a=4;PRINTF("%d", a);
}
这段代码预处理完为
int main()
{int a=4;printf("the value of " "a" " is " "%d" "\n",a);
}
##的作用是拼接两个常量
#include<stdio.h>
#define ADD_TO_SUM(num,value) value##num
int main()
{printf("%f",ADD_TO_SUM(2.12, 2023));
}
代码结果为
3.2.4 宏和函数对比
| 属性 | #define定义宏 | 函数 |
| 代码长度 | 每次使用时,宏代码都会被插入到程序中。除了非常 小的宏之外,程序的长度会大幅度增长 | 函数代码只出现于一个地方;每次使用这个函数时,都调用那个地方的同一份代码 |
| 执行速度 | 更快 | 存在函数的调用和返回的额外开销,所以相对慢一些 |
| 操作优先级 | 需要根据上下文判断 | 表达式求值更容易预测 |
| 调试 | 不可调式 | 可以逐语句调试 |
| 递归 | 宏不可以递归 | 可以递归 |
3.2.7 命名约定
把宏名全部大写
函数名不要全部大写
3.3 #undef
这条指令用于移除一个宏定义。
#undef NAME
3.4 命令行定义
许多C 的编译器提供了一种能力,允许在命令行中定义符号。用于启动编译过程。
例如:当我们根据同一个源文件要编译出一个程序的不同版本的时候,这个特性有点用处。(假定某个程序中声明了一个某个长度的数组,如果机器内存有限,我们需要一个很小的数组,但是另外一个机器内存大些,我们需要一个数组能够大些。)
#include<stdio.h>
int main()
{int array[MAX_SIZE];int i=0;for(int i=0;i<MAX_SIZE;i++)scanf("%d",&array[i]);for(int i=0;i<MAX_SIZE;i++)printf("%d",array[i]);return 0;
}
在gcc下输入 gcc -D MAX_SIZE=10 test.c
这时MAX_SIZE的值就为10

3.5 文件包含
我们已经知道, #include 指令可以使另外一个文件被编译。就像它实际出现于 #include 指令的地方一样。
这种替换的方式很简单:
预处理器先删除这条指令,并用包含文件的内容替换。
这样一个源文件被包含10次,那就实际被编译10次。
所以我们在写头文件的时候一般会加上
#ifndef _TEST_H__ //头文件名 (或者自己创建一个标识符)
#define _TEST_H__
//头文件内容
#endif
这里的代码也很好理解,判断是否有这个定义,若没有则进入下面的内容,若有则结束,解决了头文件被重复包含的问题,当然也可以这样写。
#pragma oncce
完结撒花:
🌈本篇博客的内容【程序环境和预处理】已经结束。
🌈若对你有些许帮助,可以点赞、关注、评论支持下博主,你的支持将是我前进路上最大的动力。
🌈若以上内容有任何问题,欢迎在评论区指出。若对以上内容有任何不解,都可私信评论询问。
🌈诸君,山顶见!
相关文章:
【C语言技能树】程序环境和预处理
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
数据库的三大范式
1.为什么需要数据库设计 设计数据表的时候,要考虑很多的问题: 用户需要哪些数据,我们在数据表中要保存哪一些数据怎么保证数据表中的数据的正确性如何降低数据表的冗余度开发人员怎么才能更方便的使用数据库 如果数据库设计得不合理的话,可…...
【MT7628】开发环境搭建-Fedora12安装之后无法上网问题解决
1.按照如下图所示,打开Network Connections 2.点击Network Connections,弹出如下界面...
[Android Studio]Android 数据存储-文件存储学习笔记-结合保存QQ账户与密码存储到指定文件中的演练
🟧🟨🟩🟦🟪 Android Debug🟧🟨🟩🟦🟪 Topic 发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。 📋笔记目…...
【openGauss实战9】深度分析分区表
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...
XSS跨站脚本攻击剖析与防御:初识XSS
目录 跨站脚本介绍 1. 什么是XSS跨站脚本 2. XSS跨站脚本实例 3. XSS漏洞的危害 XSS的分类 1. 反射型XSS 2. 持久性XSS XSS构造 1. 利用< >标记注射Html /Javascript 2. 利用HTML标签属性值执行XSS 3. 空格回车Tab 4. 对标签属性值转码 5. 产生自己的事件…...
Python 高级编程之网络编程 Socket(六)
文章目录一、概述二、Python socket 模块1)Socket 类型1、创建 TCP Socket2、创建 UDP Socket2)Socket 函数1、服务端socket函数2、客户端socket函数3、公共socket函数三、单工,半双工以及全双工通信方式的区别四、单工,半双工以及…...
centos学习记录
遇到的问题及其解决办法 centos7安装图形化界面 yum groupinstall ‘X Window System’ yum groupinstall -y ‘GNOME Desktop’ 安装完成后输入init 5进入图形化界面 centos7安装vmware-tools 第一步卸载open-vm-tools 输入命令 yum remove open-vm-tools 输入命令 reboot 在…...
为什么说网络安全是风口行业?
前言 “没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。 网络安全行业特点 1、就业薪资非常高,涨薪快 2021年猎聘网发布网络安全行业就业薪资行业最高人均33.77万&…...
12-PHP使用过的函数 111-120
111、rowCount if ($stmt->execute($data)) {//true//读:select//写:insert,update,delete,成功后会返回表中受影响的记录数量//!rowCount() 返回受影响的记录数量if ($stmt->rowCount() > 0) {echo 新增成功,id . $db->lastInsertId() . <hr>;} else {//…...
【JavaWeb项目】简单搭建一个前端的博客系统
博客系统项目 本项目主要分成四个页面: 博客列表页博客详情页登录页面博客编辑页 该系统公共的CSS样式 common.css /* 放置一些各个页面都会用到的公共样式 */* {margin: 0;padding: 0;box-sizing: 0; }/* 给整个页面加上背景 */ html, body{height: 100%; }body {backgrou…...
iPerf3 -M参数详解,场景分析
本文目录iPerf3 -M参数说明几个典型测试场景中应该如何设定合适的-M参数值理想局域网模型(无丢包,无抖动)高丢包,无抖动模型高丢包,高抖动模型(网络质量比较差,IP转发路径变化频繁)总…...
java的基本语法以及注意事项
Java 基础语法一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它…...
matlab搭建IAE,ISE,ITAE性能指标
目录前言准备IAEISEITAE前言 最近在使用matlab搭建控制系统性能评价指标模型,记录一下 准备 MATLAB R2020 IAE IAE函数表达式如下所示: IAE函数模型如下所示: ISE ISE函数表达式如下所示: ISE函数模型如下所示ÿ…...
docker安装mysql
在安装Mysql之前,我们可以先查看一下我们的镜像,输入命令: docker images 能发现,镜像里面只有一个Nginx,并没有Mysql 然后我们可以像上一篇安装Nginx一样,安装Mysql镜像。 输入以下命令,安装…...
Leetcode 回溯详解
回溯法 回溯法有“通用解题法”之称,用它可以系统地搜索问题的所有解。回溯法是一个既带有系统性又带有跳跃性的搜索算法。 在包含问题的所有解的解空间树中,按照深度优先搜索(DFS))的策略,从根结点出发深度探索解空间树。当探索…...
AI_Papers:第一期
2023.02.06—2023.02.12 文摘词云 Top Papers Subjects: cs.CL 1.Multimodal Chain-of-Thought Reasoning in Language Models 标题:语言模型中的多模式思维链推理 作者:Zhuosheng Zhang, Aston Zhang, Mu Li, Hai Zhao, George Karypis, Alex Sm…...
C/C++内存管理
C/C内存管理C/C内存分布C语言中内存管理的方式:malloc/calloc/realloc/freeC内存管理方式内置类型自定义类型operator new 与operator deletenew和delete的实现原理内置类型自定义类型定位new表达式(placement-new)new/delete与malloc/free的区别C/C内存分布 我们先…...
【大数据hive】hive 函数使用详解
一、前言 在任何一种编程语言中,函数可以说是必不可少的,像mysql、oracle中,提供了很多内置函数,或者通过自定义函数的方式进行定制化使用,而hive作为一门数据分析软件,随着版本的不断更新迭代,…...
彻底搞懂分布式系统服务注册与发现原理
目录 引入服务注册与发现组件的原因 单体架构 应用与数据分离...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑 在电子商务领域,转化率与网站性能是决定商业成败的核心指标。今天,我们将深入解析不同类型电商平台的转化率基准,探讨页面加载速度对用户行为的…...

