C复习-基础知识

news2025/1/18 9:58:54

参考:

  1. 里科《C和指针》
  2. Bryant, Hallaron 《深入理解计算机系统》
  3. 何昊,叶向阳《程序员面试笔试宝典》

从hello.c到可执行文件hello

在Unix系统中,从源文件到目标文件的转化是由编译器驱动程序完成的:

root> gcc -o hello hello.c

这个转化可以分为4个阶段,执行这4个阶段的预处理器、编译器、汇编器和链接器一起构成了编译系统compilation system。
在这里插入图片描述

1)预处理阶段:cpp根据#开头的命令,修改原始程序。比如#include <stdio.h>就是读取系统头文件stdio.h的内容,直接插入到程序中。输出结果以 .i 后缀

2)编译阶段:编译器ccl将文本翻译成汇编语言。汇编语言是一个通用的低级机器语言指令。输出结果以.s后缀

3)汇编阶段:汇编器as将汇编语言翻译成机器语言,并且打包成可重定位目标程序relocatable object program的格式,输出结果以.o后缀

4)链接阶段:因为hello调用了printf函数,而它是标准C库的一个函数,因而有一个名为printf.o的目标程序,因此需要使用链接器合并,最终变成可执行文件。

注意:
1)一般UNIX系统中目标文件名后缀是.o,但MS-DOS中则是.obj

2)UNIX系统中,如果编译的源文件只有一个,中间产生的.o文件会在产生完可执行文件.out后被自动删除;但如果源文件有多个,不会删除,这样的话如果改动某个源程序,编译器会只重新编译改动过的,后面再一起链接。MS-DOS在单个源文件时也不会删除目标文件

在这里插入图片描述

linux键入./hello

1)键盘键入后,USB控制器将输入通过I/O总线经过I/O桥读入寄存器,然后再经过I/O桥、内存总线存入内存。

2)当键入回车时,shell知道输入结束了,随后加载可执行的hello文件,这些指令将代码和数据从磁盘复制到主存(使用直接存储器存取DMA技术能将数据直接从磁盘复制到主存)

3)代码和数据加载完成后,CPU开始执行指令,最后将输出“hello, world\n”从主存复制到寄存器文件,再经过总线接口、I/O桥到达显示器

在这里插入图片描述

GNU项目

GNU项目(GNU’s Not Unix,1984年提出)已经开发出一个包含Unix操作系统的所有主要部件的环境,但内核除外(由Linux项目独立发展)。GNU环境包括EMACS编辑器、GCC编译器(GNU Compiler Collection)、GDB调试器、汇编器、链接器、处理二进制文件的工具喝其他一些不见。

GCC可以使用不同版本的C语言编译程序,参数是-std=xx

C版本GCC命令行值
GNU89无,-std=gnu89
ANSI, ISO C90-ansi, -std=c89
ISO C99-std=c99
ISO C11-std=c11

C90被称为C89是因为它的标准化工作是从1989年开始的。

ANSI C的任何一种实现中,都有两种环境。一是翻译环境translation environment,即将源代码转换为可执行的机器指令;二是执行环境execution environment,用于实际执行代码。这两种环境不必在同一台机器上。交叉编译器cross compiler就是在一台机器上编译,但是产生的可执行代码可以在不同机器使用。独立环境freestanding environment是指不存在操作系统的环境,比如嵌入式系统(微波炉控制器)


编码规范

字符

三字母词trigraph:原本是为了减少字符集规模,不过其实不太常用。

#include <stdio.h>
#include <stdlib.h>

void main() {
    printf("??) ??( ??! ??< ??> ??' ??= ??/ ??-");
}

编译+执行。默认是不开启的,gcc要使用-trigraphs开启

gcc -o hello hello.c -trigraphs
./hello
] [ | { } ^ #  ~

注释

如果需要注释掉一段代码,如果代码里有长段注释,可能/**/的效果不好,此时可以考虑#if和#endif,这样更安全

#if 0
statements //要注释掉的代码
#endif

数据

C中只有4种基本数据类型:整型、浮点、指针和聚合类型(如array和struct)。

整型包括:字符、短整型、整型和长整型。都有signed有符号和unsigned无符号两种版本。

标准只规定了长整型至少应该跟整型一样长,整型至少应该跟短整型一样长。因此,缺省的int是16位还是32位,通常是由编译器决定的。一般来说是字长。limits.h定义了不同的整数类型的最大最小值。

char本质是小整型值,缺省的char可能是signed char或者unsigned char,所以为了可移植起见,char变量的值应该在两者的交集中(比如ASCII),也可以显式声明(某些机器处理signed char更快,但是一些库函数的参数声明是char,显式声明可能有兼容性问题)。

int ch;
while( (ch = getchar()) != EOF && ch != '\n' );

为什么要把ch声明为int?EOF是一个整型值,如果使用char可能导致EOF解释错误

在整型字面值后添加L或l可以让整数被解释long,U或u则可以解释为unsigned,UL也可以组合

十进制整型字面值在缺省情况下,它的类型是能容纳这个值的最短类型。八进制需要以0开头,十六进制需要以0x开头。当然,使用\转义的时候,八进制格式为\ddd,十六进制格式为\xddd(此时算字符常量,所以输出是字符)

printf("\127\n"); // W
printf("\x00f\n"); // 如果数值较大会报错

宽字符常量wide character literal:当运行时环境支持一种宽字符集时,可以使用。比如使用Unicode字符集

#include <windows.h>
...
wchar_t c = L'Xs';
MessageBoxW(0, L"你好世界", L"I am", 0); // MessageBoxW默认以宽字符处理

在这里插入图片描述

枚举enumerated类型

枚举类型的值是符号常量,不是字符串。声明枚举类型的时候,实际就给符号名赋予了整数值,如下面的CUP实际就是0,PINT是1,以此类推。

enum Jar_Type {CUP, PINT, QUART, GALLON}; // 声明类型
enum Jar_Type milk_jug; // 声明枚举类型的变量

当然也可以给部分符号赋值,对于没被显式赋值的符号,就是前一个符号名的值+1

enum Jar_Type {CUP = 8, PINT, QUART, GALLON}; // 声明类型
enum Jar_Type milk_jug = PINT; // 声明枚举类型的变量
printf("%d", milk_jug); // 9

浮点数

包括float、double和long double,它们的范围存储在float.h中。浮点数必须至少有一个小数点或者指数(E/e),浮点数字面值缺省情况下是double,除非后跟L/l表示是long double,或者后跟F/f表示是float。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1104143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RTOS(4)自己的第一个FreeRTOS程序

创建两个任务 什么是任务呢&#xff1f; 对于整个单片机程序&#xff0c;我们称之为application&#xff0c;应用程序。 使用FreeRTOS时&#xff0c;我们可以在application中创建多个任务(task)&#xff0c;有些文档把任务也称为线程 (thread)。 void Task1Function(void *p…

课时4作业3

Description 某人想将手中的一张面值100元的人民币换成10元、5元、2元和1元面值的票子。要求换正好40张&#xff0c;且每种票子至少一张。问&#xff1a;有几种换法&#xff1f; Input 无输入 Output 一个数&#xff0c;表示共有多少种换法 Sample Input 1 无 Sample O…

手写一个PrattParser基本运算解析器1: 编译原理概述

点击查看 基于Swift的PrattParser项目 编译原理概述 编译原理是我们每一个程序猿必须要了解的技能, 编译原理实际上并没有啥高深的技术, 我们如果在做业务开发, 也很少会用到编译开发的知识, 但是编译原理又是我们必备的基础知识之一. 所以我们需要对编译原理的内容有一个大概的…

76.C++ STL list容器

目录 1.什么是list容器 2.list构造函数 3. 元素插⼊和删除操作 4.大小操作 5.赋值操作 6.数据存取操作 7.反转、排序 1.什么是list容器 list 是 C 标准库提供的双向链表容器。它与 vector 和 deque 不同&#xff0c;不是连续的内存块&#xff0c;而是由节点组成的链表结…

C语言——二周目——数据在内存中的存储

目录 一、整数的存储方式 二、浮点数的存储方式 一、整数的存储方式 因为CPU只有加法器&#xff0c;所以对于整型来说&#xff0c;数据在内存中通常采用补码的方式进行储存。 在这里复习一下原码、反码、补码。 正数和无符号数的原码、反码、补码相同&#xff1b; 负数的原…

考察软件开发公司的能力

当公司需要与软件外包公司合作时需要考察软件开发公司的能力和水平&#xff0c;这会涉及到很多方面的因素。需要通过综合考察和了解软件开发公司的能力和水平&#xff0c;选择合适的合作伙伴&#xff0c;确保项目的成功交付。下面分享一些关键步骤和方法&#xff0c;希望对大家…

【JVM】JVM的垃圾回收机制

JVM的垃圾回收机制 对象死亡判断方法引用计数算法可达性分析算法 垃圾回收算法标记清除法复制算法标记整理算法分代算法 Java运行时内存的各个区域,对于程序计数器,虚拟机栈,本地方法栈这三个部分区域而言,其生命周期与相关线程有关,随线程而生,随线程而灭,并且这三个区域的内存…

Excel冻结窗格

1、冻结表格首行 点击菜单栏中的“视图”&#xff0c;选择“窗口”选项卡中的“冻结窗格”下的小三角&#xff0c;再选择“冻结首行”&#xff1b; 2.冻结表格首列 点击菜单栏中的“视图”&#xff0c;选择“窗口”选项卡中的“冻结窗格”下的小三角&#xff0c;再选择“冻结…

图扑智慧仓储数据可视化监控平台

随着市场竞争加剧和市场需求的不断提高&#xff0c;企业亟需更加高效、智能且可靠的仓储物流管理方式&#xff0c;以提升企业的物流效率&#xff0c;减少其输出成本&#xff0c;有效应对市场上的变化和挑战。 图扑软件应用自研 HT for Web 产品搭建的 2D 智慧仓储可视化平台&a…

【轻松搞定】Edge 或 Google 无法上网问题

目录 前言 一、解决 Edge 无法上网的问题 1.1 键盘按下 WIN R 或 右键开始标志&#xff0c;启动运行 1.2 输入 regedit 进入注册表管理 1.3 打开到 \HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft 位置下新建项 Edge 1.4 右键 Edge 新建 DWORD (32) 文件&#xff0c…

<FPGA>好的编码风格(1)--尽量避免组合逻辑环路(Combinational Loops)

什么是组合逻辑环路&#xff1f; 组合逻辑环路&#xff08;Combinational Loops&#xff09;&#xff1a;指组合逻辑的输出信号不经过任何时序逻辑&#xff08;FF等&#xff09;&#xff0c;而是直接反馈到输入节点&#xff0c;从而构成的电路环路。 此外&#xff0c;如果直接将…

【开源分享】基于Html开发的房贷计算器,模仿新浪财经

房贷计算器是一种房贷计算的在线计算Web应用&#xff0c;按用户选择的贷款类型、贷款金额、期限、利率可计算得出每月月供参考、支付利息、还款总额这些信息。本文模仿新浪财经开发的房贷计算器。 作品预览 https://fangdai.gitapp.cn 源码地址 https://github.com/geeeeeee…

Qt5.12.12构建64位QMYSQL数据库驱动“driver not loaded”

在调用QSqlDatabase::open()时,会报错:“driver not loaded” 原因实际上是mysql 的驱动 qsqlmysql.dll 没有成功加载。 所以本篇文章将详细介绍一下:Qt5.12.12如何构建64位QMYSQL数据库驱动。 执行 写在最前,以下出现的文件路径为我自己电脑安装的路径,可根据自己的路…

vim快捷指令

普通模式—>插入模式 i:插入到当前光标的前面&#xff08;insert&#xff09; a:插入到光标的后面&#xff08;append&#xff09; o:插入到下一行 I:插入到行首 A:插入到行尾 O&#xff1a;插入到前一行 H:行首 L:页的最后一行的行首 W:光标跳到下一个单词词首 b:上一个单…

广州华锐互动:VR模拟高楼层建筑应急逃生,提供身临其境的虚拟体验

随着城市化进程的不断加速&#xff0c;高层建筑越来越多地出现在我们的生活中。然而&#xff0c;高层建筑的安全问题也日益凸显。一旦发生火灾、地震等突发事件&#xff0c;如何迅速、安全地逃离高楼成为了人们关注的焦点。近年来&#xff0c;虚拟现实&#xff08;VR&#xff0…

JUC并发编程——ForkJoin与异步回调

ForkJoin &#xff08;分支合并&#xff09; 什么是ForkJoin ForkJoin在JDK1.7出现 &#xff0c;并行执行任务&#xff0c;在大数据量下&#xff0c;能够提高效率 讯飞星火提供的说法&#xff1a; Forkjoin是一种并行计算的算法&#xff0c;用于将一个大任务分解为多个小任务…

【PSO-RFR预测】基于粒子群算法优化随机森林回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

MinIO (三) 使用Webhook实时同步文件

前言 使用MinIO的过程中&#xff0c;我们这里遇到个需求&#xff0c;系统需要预览3D文件&#xff0c;前端操作&#xff0c;用浏览3D文件的工具打开3D文件的目录即可实现在线预览功能&#xff0c;这个时候问题来了&#xff0c;MinIO上传文件后进行了编译&#xff0c;如下图 这个…

ardupilot开发 --- 外设适配器、拓展外设、AP_Periph、DroneCAN 、UAVCAN 篇

什么是外设适配器&#xff0c;为什么要拓展外设&#xff1f; 飞控的外设接口有限&#xff0c;如串口只有8个&#xff0c;I^2C只有一个&#xff0c;CAN口只有一个&#xff0c;这些接口数量如果不能满足预期的传感器数量&#xff0c;那么就需要对这些接口进行拓展&#xff0c;外…

ELK日志分析系统的详细介绍与部署

文章目录 1. ELK的概述1.1 简介1.2 使用ELK的理由1.3 ELK的主要组件1.3.1 Elasticsearch1.3.2 Kibana1.3.3 Logstash1.3.3.1 简介1.3.3.2 Logstash常用相关命令选项 1.3.3.3 Logstash 的输入和输出流1.3.4 Logstash的相关配置文件 1.3.4 Filebeat1.3.4.1 简介1.3.4.2 filebeat …