C语言学习 — 符号以及编译过程

举报
矜辰所致 发表于 2022/09/28 17:45:55 2022/09/28
【摘要】 C语言学习 — 符号以及编译过程 细节说明

一、一些符号

反斜杠

C语言的转义字符(\)主要用于标识无回显字符,也可用于表示常规字符

在这里插入图片描述

#include <stdio.h>

int main()
{
    char enter = '\n';      //  换行
    char* p = "\141\t\x62"; // \转义字符  将8进制的 141 转成10进制就是 97 然后\t为 tab 按键 16进制的62 就是 98

    printf("%s",p);
    printf("%c",enter);

    return 0;
}

在这里插入图片描述

  • C语言中的反斜杠(\)同时具有 接续符 和 转义符 的作用
  • 作为接续符使用时可直接出现在程序中
  • 作为 转义符 使用时需出现在 单引号或双引号 之间

单引号和双引号

  • C语言中的 单引号 用来表示 字符字面量

    字符字面量 编译为 对应的 ASCII码

  • 单引号括起来的单个字符代表 整数

  • C语言中的 双引号 用来表示 字符串字面量

    字符串字面量 编译为 对应的 内存地址

  • 双引号括起来的字符代表 字符指针

  • ‘a’ 表示 字符 字面量
    在内存中占一个字节
    ‘a’ + 1 表示 ‘a’ 的ASCII码加1,结果为 ‘b’

  • “a” 表示 字符串 字面量
    在内存中占2个字节
    “a” + 1 表示 指针运算,结果指向 “a” 结束符 ‘\0’

  • printf 的第一个参数被当成字符串内存地址

  • 内存的低地址空间不能再程序中随意访问
    在这里插入图片描述在这里插入图片描述

#include <stdio.h>

int main()
{
    char c = " ";//c一个字节,后面的是一个地址值4个字节,赋值给c会产生截断     

    while((c == "\t") || (c == " ") || (c == "\n"))//双引号中的值编译过后是一个地址值
    {
        scanf("%c",&c);
    }
    return 0;
}

在这里插入图片描述

分析上面的例子:

char c = “string”;

  1. 编译后字符串 “string” 的内存地址被赋值给变量 c;
  2. 内存地址占用 4个字节,而变量 c只占用一个字节;
  3. 由于类型不同,赋值后产生截断。

所以上面的例子,while语句一次也不会执行。
所以上面的例子,正确的是把所有的双引号变成单引号;变量c和单引号内对应字符的 ASCII码进行比较,变量c本身赋值为空格键的 ASCII码对应的值。

二、编译过程

在这里插入图片描述

在这里插入图片描述

预编译(预处理器)

  • 处理所有的注释,以空格代替

  • 将所有的 #define 删除,并且展开所有的宏定义

  • 处理条件编译指令 #if, #ifdef, #elif, #else, #endif

  • 处理 #include, 展开被包含的文件

  • 保留编译期需要使用的 #pragma指令

  • 预处理指令示例:
    gcc -E file.c -o file.i

编译(编译器)

对预处理文件进行词法分析,语法分析和语义分析

  • 语法分析:分析关键字,标识符,立即数等是否合法
  • 语法分析:分析表达式是否遵循语法规则
  • 语义分析:在语法分析的基础上进一步分析表达式是否合法

分析借宿后进行 代码优化 生成相应的 汇编代码文件

  • 编译指令示例:
    gcc -S file.c -o file.s

汇编

  • 汇编器将汇编代码转变为机器的可执行指令
  • 每条汇编语句几乎都对应一条机器指令
  • 汇编指令示例:
    gcc -c file.c -o file.o

链接

链接是指 将目标文件最终链接为可执行程序

  • 静态链接:目标文件 直接连接进入可执行程序(小工程项目常用方式)
  • 动态连接:在程序 启动后在动态加载目标文件(大型软件系统,方便更新局部功能,使用很多动态库,然后更新的时候,只需要更新相应的库文件,程序运行过程中加载的库文件)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

动态库使用示例:

#include <stdio.h>
#include <dlfcn.h>

int main()
{
	void* pdlib = dlopen("./dlib.so", RTLD_LAZY);
	
	char* (*pname)();
	int (*padd)(int, int);

	if(pdlib != NULL)
	{
		pname = dlsym(pdlib,"name");
        padd = dlsym(pdlib,"add");

        if((pname != NULL) && (padd != NULL))
        {
            printf("Name: %s\n",pname());
            printf("Result: %s\n",padd(2, 3));
        }

        dlclose(pdlib);
	}
    else
    {
        printf("Cannot open lib ...\n");
    }
}

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。