【【萌新的c语言学习-14】】

萌新的c语言学习14(c语言的预处理1)

我们的文件从test.c变成了test.exe
经过了编译和链接两个过程
由.c到.exe的整个大环境叫翻译环境
.exe运行的过程叫运行环境
翻译环境就是源代码可以转化成二进制文件的过程
一个工程内可以有多个.c文件 每一个文件都会经过翻译环境单独处理
test.obj
每一个编译器都会生成一个obj

#define _CRT_SECURE_NO_WARNINGS  1
#include<stdio.h>
#include<stdlib.h>
extern int Add(int x, int y);
int main()
{
    int a = 10;
    int b = 20;
    int arr[10] = { 0 };
    int i = 0;
    for (i = 0;i < 10;i++)
    {
        arr[i] = i;
    }
    for (i = 0;i < 10;i++)
    {
        printf("%d ", arr[i]);
    }
    int c = Add(a, b);
    printf("c=%d\n", c);
    return 0;
}

比如

会生成

同样的obj
目标文件经过链接器才会生成可执行程序
目标文件里面会用到标准库函数的东西
正是通过了链接器将各个链接起来
编译阶段又分为 预编译 编译 汇编

1.预编译
过程会产生一个test.i文件
相当于把我们开头声明的#include<stdio.h>包含到了文件中去
完成了头文件的包含工作
预处理还会删除注释
使用空格替换我们的注释
还有#define 的替换也是在预处理阶段完成的
总结一句话 预处理阶段完成的都是文本操作

2.编译
test.i会生成test.s
把我们的c代码翻译成汇编代码
进行了语法分析
词法分析
语义分析
符号汇总
会把test.s转化成test.o
把汇编代码转化成二进制代码

3.汇编
在我们汇编阶段的时候会既放符号又放表格
比如说我们再进行main的编译
其中的两个符号main的地址0x200里面还有add是调用的那么这个add的地址我们就会假装给一个值
4.汇编语言经过链接器会变成可执行程序test.exe
(这里面也要进行两个步骤)
1.合并段表 2.符号表的合并和重定位
就是把上面我在main中调用add会给他一个地址,那么现在我们合并之后,每个符号都有属于它自己的地址

一个程序写好了怎么运行的呢
1,程序必须载入内存
2.调用main函数
3.开始执行程序代码
4.终止main函数 也可能意外终止

预编译符号本身就有了

int main()
{
    printf("%s\n", __FILE__);
    //就是这个代码所在的路径
    printf("%d\n", __LINE__);
    //获取代码所在行数
    printf("%s\n", __DATE__);
    //打印出日期
    printf("%s\n", __TIME__);
    //打印出时间
    return 0;
}

//这些其实方便我们在以后做日志管理

举例

int main()
{
    int i = 0;
    int arr[10] = { 0 };
    FILE* pf = fopen("log.txt", "w");
    for (i = 0;i < 10;i++)
    {
        arr[i] = i;
        fprintf(pf, "file:%s line:%d date:%s tine: %s i=%d\n",
            __FILE__, __LINE__, __DATE__, __TIME__, i);
    }
    for (i = 0;i < 10;i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

在这里插入图片描述
在这里插入图片描述
日志记录
有一个特殊的__STDC__ 他是用来判断
编译器是否遵循ANSI C的标准,其值为1 ,否则未定义

#define 预处理指令
#include
#开头的指令都是预处理指令
#define后面最好不要加符号
不要写成#define MAX 10; 这样写是不对的

#define 
#define SQUARE(x) x*x
//相当于将5 替换成5*5=25
int main()
{
    int ret = SQUARE(5);
    return 0;
}
但是不全面这样写
int main()
{
    
    int ret = SQUARE(5+1);
    printf("%d", ret);
    //打印出来11  宏是直接替换的意思
    //就是你放进去之后结果是 
    5+1*5+1 这个结果是11
        宏是完成替换并不是传参

    return 0;
}
写宏替换之后要记得加上括号 避免不必要的扰动
字符串出现的内容并不会被替换

```c
#define PRINT(x) printf("the value of x is %d",x)
int main()
{
    /*printf("helloworld\n");
    printf("hello""world\n");
    printf("he""llo"" world\n");*/
    //C语言字符串天然的就连在一起
    int a = 10;
    int b = 20;
    PRINT(a);
    PRINT(b);
    return 0;
}

//这样写还是不对
那么我们c语言怎么把宏中的东西传递到字符串中呢

#define PRINT(x) printf("the value of" #x"  is %d",x)
int main()
{
    /*printf("helloworld\n");
    printf("hello""world\n");
    printf("he""llo"" world\n");*/
    //C语言字符串天然的就连在一起
    int a = 10;
    int b = 20;
    PRINT(a);
    PRINT(b);
    return 0;
}

在这里插入图片描述
这样子就对了

#define CAT(x,y) x##y
int main()
{
    int Class84 = 2019;
    printf("%d\n", Class84);
    printf("%d\n", CAT(Class,84));
    return 0;
    //  ## 会把两端的符号拼起来 最后这个数字不就是Class84吗

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值