预处理指令
宏定义(#define, #undef),文件包含(#include),条件编译(#ifdef, #if, #elif,#else,#endif)
预处理指令全部以 # 开头
在#define中,如果要书写多行,则必须在当前行最后加上 ** ,才可以继续书写下下一行:

#define DISK_CAPACITY (SIDES*               \
                       TRACKS_PER_SIDE*     \
                       SECTORS_PER_TRACK    \   
                       BYTES_PER_SECTOR)

对于 带参数的宏定义 而言,类似于这样的参数是有 副作用 的:
i++

#和##运算符

来看一下下面这个神奇的操作:

#define PRINT_INT(n) printf(#n" = %d\n", n)
int main() {
    int g = 3;
    PRINT_INT(g);
    return 0;

上面这段代码中的在经过预处理之后是这样的:

printf("g"" = %d\n", n);

在C语言中,两个相邻的字符串会被合并,也就是说,上面的代码段为:

printf("g = %d\n", n);

输出结果为:
C语言学习笔记(一)_#include
#运算符会宏将的一个参数转换为字符串字面量,也就是说,n会被替换成g这个字符

再来看一下##运算符

#include<stdio.h>
#define PRINT_INT(n) printf(#n" = %d\n", n)
#define MK_ID(n) i##n=0
int main() {
    int MK_ID(1), MK_ID(2), MK_ID(3);
    PRINT_INT(i1+i2+i3);
    return 0;

输出结果:
C语言学习笔记(一)_#define_02
##运算符可以将两个计号(标识符)粘结在一起,可以看到上面代码中的MK_ID(n)宏,会把穿进去的参数和i连接在一起,成为了变量in,使用这个宏,我们就能快速定义并初始化一系列变量

__LINE__    被编译文件的行号
__FILE__    被编译的文件名
__DATE__    编译的日期
__TIME__    编译的时间
__STDC__    如果编译器符合C标准(C89或C98),那么其值为1
#include<stdio.h> 
#define PRINT_INT(n) printf(#n" = %d\n", n)
#define PRINT_CHAR(str) printf(#str" = %s\n", str) 
int main() {
    PRINT_INT(__LINE__);    //  被编译文件的行号
    PRINT_CHAR(__FILE__);   //  被编译的文件名
    PRINT_CHAR(__DATE__);   //  编译的日期
    PRINT_CHAR(__TIME__);   //  编译的时间
    PRINT_INT(__STDC__);    //  如果编译器符合C标准(C89或C98),那么其值为1
    return 0;

C语言中是允许空的宏参数的

#include<stdio.h> 
#define PRINT_INT(n) printf(#n" = %d\n", n) 
#define ADD(i,j) i+j
int main() {
    int k = 101;
    int i = ADD(,k);
    PRINT_INT(i);
    return 0;

C语言学习笔记(一)_其他_04
_fun_标识符

#include <stdio.h>
#define FUNCTION_CALLED() printf("%s called\n", __func__);
void fun() {
    FUNCTION_CALLED(); 
int main(void) {
    fun();
    return 0;

_fun_表示调用自己的是哪个函数

条件编译中的所有关键字:

defined #ifdef #elif #else #endif

条件编译多在调试的时候会用到:

#include <stdio.h>
#define DEBUG 1
int main(void) {
    printf("%s called\n", __func__);
    #if DEBUG
    printf("HELOO\n"); 
    #endif
    return 0;
#include <stdio.h>
*******************************************
#define DEBUG 0
int main(void) {
    printf("%s called\n", __func__);
    #if DEBUG
    printf("HELOO\n"); 
    #endif
    return 0;
*******************************************
#include <stdio.h>
#define DEBUG
int main(void) {
    printf("%s called\n", __func__);
    #if defined DEBUG
    //等价于ifdef DEBUG
    printf("HELOO\n"); 
    #endif
    return 0;

我们可以通过控制DEBUG宏的定义与否来控制是否输出中间结果
注意使用#if DEBUG的时候,判断结果跟DEBUG是有关的,0的时候为1的时候为
但在使用#if defined DEBUG或者ifedf DEBUG的时候,是不需要对DEBUG作准确的定义的,defined(ifdef)只是检查DEBUG是否被声明为一个Macro

 #ifdef DEBUG = #if defined DEBUG

这两句话是完全等价的,

mysql 有数据然后新增字段位自增主键

准备见MySQL---当Java遇上MySQL②自动增长字段获取自动增长字段的值演示 Statement 获取@Test //为演示直观 异常直接抛了 public void saveAutoIncrement1() throws Exception { Connection con = ConnUtil.getConnection(); Statement st = con.creat