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语言特点

  1. 结构化编程:C语言采用结构化编程的思想,代码结构清晰简洁,易于理解和维护。

  2. 代码可移植性:C语言的编译器可以在多种平台上运行,代码可以在不同的操作系统和硬件上运行,具有很好的可移植性。

  3. 高效性:C语言的编译器生成的代码执行效率高,能够直接操作计算机硬件,利用底层资源,具有高效性。

  4. 指针:C语言具有指针的概念,可以直接访问内存地址,实现高效的数据操作。

  5. 库函数丰富:C语言提供了丰富的标准库函数,能够方便地实现各种功能,如字符串操作、文件操作等。

  6. 可扩展性:C语言可以使用其他语言编写的库文件,扩展其功能。

  7. 低级别控制:C语言具有低级别的控制能力,用户可以直接控制内存、硬件等底层资源,实现灵活的编程。

  8. 面向过程: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语言是一种基于过程的编程语言,具有以下几个基本机制:

  1. 结构化编程:C语言通过控制结构(如if-else、while、for等)来组织代码,实现结构化编程,使代码清晰、易于理解和修改。

  2. 函数:C语言中的函数是一个独立的代码块,接受一些输入参数并返回一个输出值。通过函数,可以将代码分解成小的模块,提高了代码的可读性和可维护性。

  3. 指针:指针是C语言中的一种重要数据类型,可以指向内存中的地址,允许对内存中的数据进行直接访问和操作。指针在C语言中被广泛使用,可以用来实现高效的数据结构和算法。

  4. 数据类型:C语言中定义了基本的数据类型,如整数、字符、浮点数等,也可以通过结构体和联合体来自定义复杂的数据类型,以满足不同的需求。

  5. 预处理器: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.c146B9
预处理后test.i17691B857

预处理之后的程序还是文本,可以用文本编辑器打开。

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命令的时候没有关心中间结果,但每次程序的编译都少不了这几个步骤。也不用为上述繁琐过程而烦恼,因为你仍然可以:

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI 绘画 | Stable Diffusion 进阶 Embeddings(词嵌入)、LoRa(低秩适应模型)、Hypernetwork(超网络)

前言 Stable Diffusion web ui,除了依靠文生图(即靠提示词生成图片),图生图(即靠图片提示词生成图片)外,这两种方式还不能满足我们所有的绘图需求,于是就有了 Embeddings&#xff0…

【vue】vue项目批量下载二维码,且打包成压缩包.

一. 先看效果演示 二. 下插件 npm i vue-qr -S // 二维码显示插件 我的版本^4.0.9 npm i html2canvas -S // 将二维码转为图片 我的版本^1.4.1 npm i file-saver -S // 下载图片 我的版本^2.0.5 npm i jszip -S // 打包成压缩包 我的版本^3.10.1 // 一次性下载 npm i vue-qr h…

DDoS攻击剧增,深入解析抗DDoS防护方案

当下DDoS攻击规模不断突破上限,攻击方式越发复杂。面对复杂的攻击形式,对于企业和组织来说无疑需要更完备的抗DDoS方案,依靠传统的解决方法并不能做到一劳永逸。在服务器抵抗DDoS防护上,你不会忽略F5的产品,让我们一起…

uniapp中在组件中使用被遮挡或层级显示问题

uniapp中在组件中使用或croll-view标签内使用uni-popup在真机环境下会被scroll-view兄弟元素遮挡,在开发环境下和安卓系统中可以正常显示,但在ios中出现了问题 看了许多文章都没有找到问题的原因,最后看到这一个文章http://t.csdnimg.cn/pvQ…

【Spring】Spring IOC DI

Spring IOC & DI IOC DI入门什么是Spring什么是容器什么是IOC IOC介绍传统程序开发解决方案 DI IOC详解Bean的存储Controller(控制器存储)Service(服务存储)Repository(仓库存储)Component(组件存储)Configuration(配置存储) 为什么需要这么多类注解类注解之间的关系方法注…

实战Leetcode(三)

Practice makes perfect! 实战一: 带环问题其实我们小学时就接触过,就比如在操场上比赛跑步的追击问题,这里也是一样,如果我们定义两个指针,一个快指针,一个慢指针,快指针走的快&…

云栖大会丨桑文锋:打造云原生数字化客户经营引擎

近日,2023 云栖大会在杭州举办。今年云栖大会回归了 2015 的主题:「计算,为了无法计算的价值」。神策数据创始人 & CEO 桑文锋受邀出席「生态产品与伙伴赋能」技术主题,并以「打造云原生数字化客户经营引擎」为主题进行演讲。…

【多线程 - 01、概述】

进程 几乎所有的操作系统都支持进程概念,进程是处于运行过程中的程序,进程是操作系统中进行资源分配的基本单位。 三个基本特征 独立性:指进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。而对于未建立任何进程的程序&…

RabbitMQ集群

RabbitMQ概述 1.RabbiMQ简介 RabbiMQ是⽤Erang开发的,集群⾮常⽅便,因为Erlang天⽣就是⼀⻔分布式语⾔,但其本身并不⽀持负载均衡。支持高并发,支持可扩展。支持AJAX,持久化,用于在分布式系统中存储转发消…

C/C++数字判断 2021年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C数字判断 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C数字判断 2021年9月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 输入一个字符,如何输入的字符是数字&#x…

栈 和 队列

什么是栈? 一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出(LIFO - Last In First Out)的原则。   从数据结构的角度来看&…

数据结构与算法【二分查找】Java实现

需求:在有序数组 A 内,查找值target 如果找到返回索引如果找不到返回 -1 前提 给定一个内含 n 个元素的有序数组 A,一个待查值 target 1 设置 i0,jn-1 2 如果 i \gt j,结束查找,没找到 3 设置 m (…