C语言概述
目录
编辑
1. C语言发展史
2. C语言特点
3. C语言标准
4. C语言编程机制
4.1 预处理(Preprocessing)
4.2 编译(Compilation)
4.3 汇编(Assemble)
4.4 链接(Linking)
结语
1. C语言发展史
C语言是由美国贝尔实验室的Dennis Ritchie于1972年设计开发的一种编程语言,它的设计目标是用于Unix操作系统的程序开发。
在20世纪70年代末和80年代初,C语言逐渐成为主流的编程语言之一。它的广泛应用在于其简单易学、功能强大、可移植性强的特点,使得许多计算机公司和软件开发者将其作为首选语言。
1990年代中期,C++语言的出现逐渐压过了C语言的优势。尽管如此,C语言仍然是许多高性能应用程序的编程语言,包括操作系统、嵌入式系统和设备驱动程序等。
近年来,由于其广泛应用和高度成熟的编译器、文档和支持工具,C语言仍然是许多计算机科学教育课程的核心部分。此外,许多新的C语言标准和框架也在不断推出,以满足不断变化的编程需求。

2. C语言特点
-
结构化编程:C语言采用结构化编程的思想,代码结构清晰简洁,易于理解和维护。
-
代码可移植性:C语言的编译器可以在多种平台上运行,代码可以在不同的操作系统和硬件上运行,具有很好的可移植性。
-
高效性:C语言的编译器生成的代码执行效率高,能够直接操作计算机硬件,利用底层资源,具有高效性。
-
指针:C语言具有指针的概念,可以直接访问内存地址,实现高效的数据操作。
-
库函数丰富:C语言提供了丰富的标准库函数,能够方便地实现各种功能,如字符串操作、文件操作等。
-
可扩展性:C语言可以使用其他语言编写的库文件,扩展其功能。
-
低级别控制:C语言具有低级别的控制能力,用户可以直接控制内存、硬件等底层资源,实现灵活的编程。
-
面向过程:C语言是一种面向过程的编程语言,适合于开发底层的系统软件和高效的算法。
通过上述的介绍,已经了解了C语言的若干特点。C语言虽然是一种优秀的计算机程序设计语言,但也存在以下的一些缺点,了解这些缺点,才能够在实际使用中扬长避短。
1. C程序的错误更隐蔽。C语言的灵活性使得用它编写程序时更容易出错,而且C语言的编译器不检查这样的错误。与汇编语言类似,需要程序运行是才能发现这些逻辑错误。C语言还会有一些隐患,需要程序员重视,比如将比较的"=="写成赋值"=",语法上没有错误,这样的逻辑错误不易发现,要找出来往往十分费时。
2. C程序有时会难以理解。C语言语法成分相对简单,是一种小型语言。但是,其数据类型多,运算符丰富且结合性多样,使得对其理解有一定的难度。有关运算符和结合性,人们最常说的一句话是“先乘除,后加减,同级运算从左到右”,但是C语言远比这要复杂。发明C语言时,为了减少字符输入,C语言比较简明,同时也使得C语言可以写出常人几乎无法理解的程序。
3. C程序有时会难以修改。考虑到程序规模的大型化或者说巨型化,现代编程语言通常会提供“类”和“包”之类的语言特性,这样的特性可以将程序分解成更加易于管理的模块。然而C语言缺少这样的特性,维护大型程序显得比较困难。
3. C语言标准
C语言标准通常指ISO/IEC 9899:C99或ISO/IEC 9899:C11。这些标准定义了C程序语言的语法、语义、库等的规范。C99是C语言的第二个国际标准,于1999年发布,引入了许多新功能,如可变长度数组、复合文字和行注释等,C11于2011年发布,进一步扩展了C99,并添加了一些新功能,如泛型选择和多线程库等。
4. C语言编程机制
编程机制是指在计算机程序中使用的各种规则和技术,包括程序设计、算法、数据结构、编程语言、编码标准、调试和测试等方面。其中,程序设计是编程机制的核心,它涉及到如何组织和设计程序的核心逻辑和数据结构,以及如何在其中使用编程语言和库。算法则是指在程序中描述问题的解决方案的过程或序列,数据结构则是指程序中用于存储和操作数据的方式。编程语言则提供了一种语法和语义规则来实现特定的编程机制,编码标准则规定了程序如何编写、格式化和文档化。调试和测试等技术则用于发现和修复程序中的错误和缺陷。综合使用这些机制可以编写高效、可靠、可维护和易于使用的程序。
C语言是一种基于过程的编程语言,具有以下几个基本机制:
-
结构化编程:C语言通过控制结构(如if-else、while、for等)来组织代码,实现结构化编程,使代码清晰、易于理解和修改。
-
函数:C语言中的函数是一个独立的代码块,接受一些输入参数并返回一个输出值。通过函数,可以将代码分解成小的模块,提高了代码的可读性和可维护性。
-
指针:指针是C语言中的一种重要数据类型,可以指向内存中的地址,允许对内存中的数据进行直接访问和操作。指针在C语言中被广泛使用,可以用来实现高效的数据结构和算法。
-
数据类型:C语言中定义了基本的数据类型,如整数、字符、浮点数等,也可以通过结构体和联合体来自定义复杂的数据类型,以满足不同的需求。
-
预处理器:C语言中的预处理器可以在编译代码之前对代码进行一些预处理,如包含头文件、定义常量、条件编译等,可以使代码更加灵活和可配置。
以上这些机制共同构成了C语言的编程范式,使其成为一种高效、灵活、可扩展的编程语言。
4.1 预处理(Preprocessing)
预处理用于将所有的#include头文件以及宏定义替换成其真正的内容,预处理之后得到的仍然是文本文件,但文件体积会大很多。gcc的预处理是预处理器cpp来完成的,你可以通过如下命令对test.c进行预处理:
gcc -E -I./inc test.c -o test.i
或者直接调用cpp命令
$ cpp test.c -I./inc -o test.i
上述命令中-E是让编译器在预处理之后就退出,不进行后续编译过程;-I指定头文件目录,这里指定的是我们自定义的头文件目录;-o指定输出文件名。
经过预处理之后代码体积会大很多:
| X | 文件名 | 文件大小 | 代码行数 |
|---|---|---|---|
| 预处理前 | test.c | 146B | 9 |
| 预处理后 | test.i | 17691B | 857 |
预处理之后的程序还是文本,可以用文本编辑器打开。
4.2 编译(Compilation)
这里的编译不是指程序从源文件到二进制程序的全部过程,而是指将经过预处理之后的程序转换成特定汇编代码(assembly code)的过程。编译的指定如下:
$ gcc -S -I./inc test.c -o test.s
上述命令中-S让编译器在编译之后停止,不进行后续过程。编译过程完成后,将生成程序的汇编代码test.s,这也是文本文件,内容如下:
// test.c汇编之后的结果test.s.file "test.c".section .rodata
.LC0:.string "a=%d, b=%d, a+b=%d\n".text.globl main.type main, @function
main:
.LFB0:.cfi_startprocpushl %ebp.cfi_def_cfa_offset 8.cfi_offset 5, -8movl %esp, %ebp.cfi_def_cfa_register 5andl $-16, %espsubl $32, %espmovl $2, 20(%esp)movl $3, 24(%esp)movl 24(%esp), %eaxmovl %eax, 4(%esp)movl 20(%esp), %eaxmovl %eax, (%esp)call add movl %eax, 28(%esp)movl 28(%esp), %eaxmovl %eax, 12(%esp)movl 24(%esp), %eaxmovl %eax, 8(%esp)movl 20(%esp), %eaxmovl %eax, 4(%esp)movl $.LC0, (%esp)call printfleave.cfi_restore 5.cfi_def_cfa 4, 4ret .cfi_endproc
.LFE0:.size main, .-main.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2".section .note.GNU-stack,"",@progbits
请不要问我上述代码是什么意思!-_-
4.3 汇编(Assemble)
汇编过程将上一步的汇编代码转换成机器码(machine code),这一步产生的文件叫做目标文件,是二进制格式。gcc汇编过程通过as命令完成:
$ as test.s -o test.o
等价于:
gcc -c test.s -o test.o
这一步会为每一个源文件产生一个目标文件。因此mymath.c也需要产生一个mymath.o文件
4.4 链接(Linking)
链接过程将多个目标文以及所需的库文件(.so等)链接成最终的可执行文件(executable file)。
命令大致如下:
$ ld -o test.out test.o inc/mymath.o ...libraries...
结语
经过以上分析,我们发现编译过程并不像想象的那么简单,而是要经过预处理、编译、汇编、链接。尽管我们平时使用gcc命令的时候没有关心中间结果,但每次程序的编译都少不了这几个步骤。也不用为上述繁琐过程而烦恼,因为你仍然可以:

相关文章:
C语言概述
目录 编辑 1. C语言发展史 2. C语言特点 3. C语言标准 4. C语言编程机制 4.1 预处理(Preprocessing) 4.2 编译(Compilation) 4.3 汇编(Assemble) 4.4 链接(Linking) 结语 1. C语言发展史 C语言是由美国贝尔实验室的Dennis Ritchie于1972年设计开发的一种编…...
elasticsearch分词器
内置分词器 Standard Analyzer - 默认分词器,英文按单词词切分,并小写处理Simple Analyzer - 按照单词切分(符号被过滤), 小写处理Stop Analyzer - 小写处理,停用词过滤(the,a,is)Whitespace Analyzer - 按照空格切分,不转小写Ke…...
# 深度解析 Socket 与 WebSocket:原理、区别与应用
在网络通信领域,Socket和WebSocket都是关键的技术,但它们背后的原理和应用有着显著的差异。本文将深入剖析Socket与WebSocket的工作原理,突出它们之间的区别,并探讨它们在不同场景下的应用。 1. Socket 的基础 1.1 什么是 Socke…...
C++17中std::optional的使用
模版类std::optional管理一个可选的(optional)存储值(contained value),即可能存在也可能不存在的值。std::optional的一个常见用例是存储可能失败的函数的返回值。与其它方法相反(例如std::pair<T, bool>),std::optional可以很好地处理构造成本高昂的对象&am…...
c++求三个数的最小公倍数
答案: #include <iostream> using namespace std; int main() {int n1, n2, n3, max;cin >> n1 >> n2 >> n3;max (n1 > n2 > n3) ? n1 : n2;do{if (max % n1 0 && max % n2 0 && max % n3 0){cout << ma…...
Flink 基础 -- 尝试Flink
官网 文档 v1.18.0 下载 数据流上的状态计算(Stateful Computations over Data Streams) Apache Flink是一个框架和分布式处理引擎,用于无界和有界数据流的有状态计算。Flink被设计成可以在所有常见的集群环境中运行,以内存中的速度和任何规模执行计…...
kubeadm部署k8s及高可用
目录 CNI 网络组件 1、flannel的功能 2、flannel的三种模式 3、flannel的UDP模式工作原理 4、flannel的VXLAN模式工作原理 5、Calico主要组成部分 6、calico的IPIP模式工作原理 7、calico的BGP模式工作原理 8、flannel 和 calico 的区别 Kubeadm部署k8s及高可用 1、…...
GEE:将鼠标变成十字指针,点击获取影像值,显示值到UI中
作者:CSDN @ _养乐多_ 本文记录了在 Google Earth Engine(GEE)开发中,将鼠标变成十字指针,点击获取影像值,显示值到UI中的代码片段。这段代码复制过去修改变量名就可以用了。 效果如下图所示, 文章目录 一、代码片段一、代码片段 使用的时候将 YLDImage 变量换成你屏…...
SpringBoot 项目公共字段填充
[公共字段自动填充] 核心:在切面类中捕获需要填充公共字段的 Mapper 方法,方法上使用注解加以标识,通过反射拿到需要填充的字段赋值方法,进行赋值操作 1、自定义注解 AutoFill Target(ElementType.METHOD) Retention(RetentionPo…...
分布式搜索引擎ES
文章目录 初识elasticsearch了解ES倒排索引正向索引倒排索引正向和倒排 es的一些概念文档和字段索引和映射mysql与elasticsearch 安装ES部署kibana安装IK分词器扩展词词典停用词词典 索引库操作mapping映射属性索引库的CRUD创建索引库和映射查询索引库修改索引库删除索引库 文档…...
2023年05月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试
Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 下列程序段的运行结果是?( ) def s(n):if n==0:return 1else:...
@KafkaListener注解详解(一)| 常用参数详解
KafkaListener 注解提供了许多可配置的参数,以便更灵活地定制 Kafka 消息监听器的行为。 topics: 描述: 指定监听的 Kafka 主题,可以是一个字符串数组。这是最基本的参数,它定义了监听器将从哪个或哪些主题接收消息。…...
蓝桥杯算法双周赛心得——被替换的身份证(分类讨论)
大家好,我是晴天学长,分类讨论一定要细节啊,需要的小伙伴可以关注支持一下哦!后续会继续更新的。💪💪💪 1) .被替换的身份证 2) .算法思路 假设一方获胜 1.接受数据 2.假设潜梦醒 无非就是&am…...
实验一:人工智能之启发式搜索算法(含源码+实验报告)
✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :hfut实验课设 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!没有人会关心你付出过多少…...
C++学习 --类和对象之封装
目录 1, 什么是封装 2, 创建类 3, 权限控制 3-1, public权限 3-2, private权限 3-3, protected权限 3-4, 类外访问私有属性 4, 构造函数 4-2,创建构造函数 4-2…...
在Spring Boot中使用JTA实现对多数据源的事务管理
了解事务的都知道,在我们日常开发中单单靠事务管理就可以解决绝大多数问题了,但是为啥还要提出JTA这个玩意呢,到底JTA是什么呢?他又是具体来解决啥问题的呢? JTA JTA(Java Transaction API)是…...
介绍YOLO-NAS Pose:姿势估计的技术
YOLO-NAS 姿势 YOLO-NAS Pose models是对 Pose Estimation 领域的最新贡献。今年早些时候,Deci 因其突破性的目标检测基础模型 YOLO-NAS 获得了广泛认可。在 YOLO-NAS 成功的基础上,该公司现在推出了 YOLO-NAS Pose 作为其姿势估计的对应产品。该姿势模型在延迟和准确性之间…...
计算机毕业设计 基于SpringBoot的实训管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
Python开发运维:Python3.7使用QQ邮箱发送不同类型邮件
目录 一、理论 1.邮件发送 二、实验 1.Python3.7使用QQ邮箱发送普通邮件 2.Python3.7使用QQ邮箱发送包含图片与附件的邮件 三、问题 1.Pycharm中如何放大和缩小代码界面 一、理论 1.邮件发送 (1)概念 SMTP(Simple Mail Transfer Pro…...
二十三种设计模式全面解析-解密迭代器模式:探索遍历之道
在软件开发中,遍历数据集合是一个非常常见的需求。但是,如何以一种优雅、灵活的方式遍历集合,并且能够适应各种不同的数据结构和迭代方式,一直是开发者们面临的挑战。今天,我将带你深入探索迭代器模式(Iter…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

