Linux之C编程入门

目录

第1关:第一个C程序

任务描述

相关知识

编译C程序

编程要求

答案及其步骤:

 第2关:Linux编译C程序

任务描述

相关知识

gcc编译器使用方法

编程要求

答案及其步骤: 

第3关:Linux之静态库编写 

任务描述

相关知识

生成静态库

使用静态库

编程要求

答案及其步骤:

第4关:Linux之动态库编写

任务描述

相关知识

生成动态库

使用动态库

更新/etc/ld.so.cache来运行动态库

修改LD_LIBRARY_PATH环境变量

编程要求

答案及其步骤: 


第1关:第一个C程序

任务描述

本关任务:在Linux系统上编写第一个C语言程序Hello world

相关知识

C语言是Linux操作系统中最常用的编程语言,部分原因在于Linux操作系统本身几乎是采用C语言编写的。使用C语言,程序员可以通过函数库和系统调用非常容易地访问系统服务。另外,还有很多有用的工具为程序开发和维护提供了便利。

本实训将讲解如何编译和链接C语言程序,假设用户掌握了C语言的基本语法。在Windows系统上我们编写C语言程序,我们只需在IDE(windows常使用的IDEvisual studio系列)中写入代码,然后点击编译,如果程序没有语法错误则会生成可执行文件,然后点击运行即可运行生成的可执行文件。其实IDE帮助我们自动的编译和运行程序,所以我们不需要关注程序是如何被编译的,而在Linux系统上我们通常要学会如何使用命令来编译程序,此时,我们需要手动的去编译程序,然后手动的运行程序。

编译C程序

Linux系统上常用的C编译器是gcc,大多数开发板都包含了这个工具。

gcc是开源领域应用最广泛的编译器之一,其具有功能强大,编译代码支持性能优化等特点。而Windows系统上常用的编译器叫cl.exe,该编译器就是Visual Studio集成开发环境所使用的默认编译器。当我们点击编译按钮,Visual Studio则会自动帮我们调用cl.exe编译器去编译我们所写的程序。

使用gcc编译C程序非常简单,可以使用如下命令来编译程序:

gcc 源文件

案例演示1:

使用vim编辑器编写一个“Hello world”C程序,并将源文件保存为test.c,然后编译运行test.c,可以使用如下命令:

vim test.c
gcc test.c
./a.out

使用vim编写如下代码

#include <stdio.h>
int main()
{
    printf("Hello world\n");
    return 0;
}

[请在右侧“命令行”里直接体验]

注意
 

`gcc`默认使用`a.out`作为可执行文件的名字;
./a.out表示运行当前目录下的a.out命令;
编程要求

本关任务是学会使用gcc编译C程序。

具体编程要求如下:

在当前目录下编写一个简单的C程序,输入“Hello world”字符串;

使用gcc编译生成a.out可执行文件;

答案及其步骤:

首先输入如下:

vim test.c    //使用vim编辑器编写,并将源文件保存为test.c

进入编写如下c语言代码:

#include <stdio.h>
int main()
{
    printf("Hello world\n");
}

按i键开始编写

编写完后按Esc键退出编写模式,按Shift键+:键,输入wq保存并退出

gcc test.c    //编译test.c
./a.out    //运行test.c

 第2关:Linux编译C程序

 

任务描述

本关任务:学会gcc编译器的基本使用方法。

相关知识

通过上一关内容学会了如何使用gcc命令来编译C程序,本关将进一步学习gcc编译器。

C语言程序从源代码到二进制行程序需要经历如下四个步骤:
 

预处理
编译
汇编
链接

[C语言编译流程]

预处理 预处理是根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内容上有所不同。

编译 编译是指将预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后,产生相应的汇编代码文件。

汇编 汇编是指将编译完的汇编代码文件翻译成机器指令,并生成可重定位目标程序的.o文件,该文件为二进制文件,字节编码是机器指令。

链接 链接过程是指链接器将一个个目标文件(或许还会有库文件)链接在一起生成一个完整的可执行程序,这个可执行程序才是我们最后直接执行的文件。

gcc编译器使用方法

gcc命令具体使用方法如下:

gcc  命令选项 参数

常用命令选项如下:

-o:指定生成的输出文件名字;
-E:仅执行编译预处理;
-S:将C代码转换为汇编代码;
-c:仅执行编译和汇编操作,不进行连接操作;
-I:包含库的头文件路径(大写i);
-L:指定库所在的路径;
-l:指定使用的库(小写l);

案例演示1:

使用vim编辑器编写一个“Hello world"C程序,并将源文件保存为test.c,编译test.c,指定输出可执行文件为test,并运行test,可以使用如下命令:

gcc test.c -o test
./test

使用vim编写如下代码

#include <stdio.h>
int main()
{
    printf("Hello world\n");
    return 0;
}

[请在右侧“命令行”里直接体验]

案例演示2:

仅编译test.c生成汇编语言,可以使用如下命令:

gcc -S test.c

[请在右侧“命令行”里直接体验]

注意编译生成的汇编文件使用.s为后缀名,汇编生成的二进制文件使用.o为后缀名。

 

编程要求

本关任务是学会使用gcc编译C程序。

具体编程要求如下:

在当前目录下编写一个简单的C程序,输入“Hello GCC”字符串;

使用gcc编译生成名为firstExec的可执行文件;

答案及其步骤: 

首先输入如下:

vim test.c    //使用vim编辑器编写,并将源文件保存为test.c

进入编写如下c语言代码:

#include <stdio.h>
int main()
{
    printf("Hello GCC\n");
}

按i键开始编写


编写完后按Esc键退出编写模式,按Shift键+:键,输入wq保存并退出

 

gcc test.c -o firstExec    //编译test.c文件,并指定生成的输出出文件的名字
./firstExec    //运行firstExec文件

第3关:Linux之静态库编写 
任务描述

本关任务:学会在Linux系统上生成C语言的静态库。

相关知识

在实际的软件开发时, 应该遵守一个基本原则:不要重复造轮子。如果某些代码经常要用到,不仅这个项目能使用,而且也能复用到其它项目上,那么就应该把这部分代码从项目中分离出来,将其编译为库文件,供需要的程序调用。

程序库分为两类,分别是静态库动态库。本关将主要讲解如何生成静态库

Windows系统上的静态库是以.lib为后缀,而Linux系统上的静态库是以.a为后缀的特殊的存档。

Linux系统的标准系统库可在目录/usr/lib/lib中找到。比如,在类Unix系统中C语言的数序库一般存储为文件/usr/lib/libm.a。该库中函数的原型声明在头文件/usr/include/math.h中。

生成静态库

Linux下,我们可以使用gccar工具制作和使用自己的静态库,具体过程如下:

将源码文件编译成.o目标文件;
使用ar工具将多个目标文件打包成.a的静态库文件;

注意Linux系统上默认的静态库名格式为:libxxx.a,其中xxx为生成库的名称。

案例演示1:

编写一个函数printHello,其功能为打印“Hello world"字符串,将其编译生成名为Hello的静态库,可以使用如下命令:

vim printHello.h
vim printHello.c
gcc -c printHello.c -o printHello.o
ar rcs libHello.a printHello.o

使用vim编写printHello.h(声明printHello函数,方便以后被其它程序调用)

#ifndef __PRINTHELLO_H__
#define __PRINTHELLO_H__
#include <stdio.h>
void printHello();
#endif

使用vim编写printHello.c

#include <stdio.h>

void printHello()
{
    printf("Hello world\n");
}

[请在右侧“命令行”里直接体验]

使用静态库

静态库的使用方法只需要在编译程序的时候指明要链接的库名称即可,gcc中有两个参数是关于链接库时所使用的,分别是:-L-l

-L:用于告诉gcc要链接的库所在目录;
-l:用于指明链接的库名称(小写l);

案例演示1:

调用以上案例生成的printHello函数,可以使用如下命令:

vim main.c
gcc main.c -o exe -L ./ -lHello
./exe

使用vim编写main.c
 

#include "printHello.h"
int main()
{
    printHello();
    return 0;
}

[请在右侧“命令行”里直接体验]

 

编程要求

本关任务是学会生成和使用静态库。

具体编程要求如下:

在当前目录下编写一个简单的函数int Add(int a, int b),其功能为计算输入参数a+b的结果;

将Add函数编译生成一个静态库libAdd.a,并存放在当前目录下;

答案及其步骤:
vim Add.h    

 进入如下输入:

#include<stdio.h>
int Add(int a,int b);

vim Add.c

 进入如下输入:

#include<stdio.h>
int Add(int a,int b)
{
    return a+b;
}

gcc -c Add.c -o Add.o
ar rcs libAdd.a Add.o
vim main.c

 进入如下输入:

#include "Add.h"
int main()
{
    int c=Add(1,1);
    return c;
}

gcc main.c -o exe -L ./ -lAdd
./exe

全部输入如下:

第4关:Linux之动态库编写

 

任务描述

本关任务:学会在Linux系统上生成C语言的动态库。

相关知识

上一关学习了如何生成静态库,本关将继续讲解如何生成动态库

静态库动态库的区别:

静态库动态库
名称命名方式是"libxxx.a",库名前加"lib",后缀用".a","xxx"为静态库名命名方式是"libxxx.so", 库名前加"lib",后缀用".so", "xxx"为动态库名
链接时间静态库的代码是在编译过程中被载入程序中动态库在编译的时候并没有被编译进目标代码,而是当你的程序执行到相关函数时才调用该函数库里的相应函数
优点在编译后的执行程序不在需要外部的函数库支持,因为所使用的函数都已经被编进去了。动态库的改变并不影响你的程序,所以动态函数库升级比较方便
缺点如果所使用的静态库发生更新改变,你的程序必须重新编译因为函数库并没有整合进程序,所以程序的运行环境必须提供相应的库

Windows系统上的动态库是以.dll为后缀,而Linux系统上的动态库是以.so为后缀的特殊的存档。

生成动态库

Linux下,我们可以使用gcc制作和使用动态库,具体制作过程如下:

使用gcc命令加-fPIC参数将源码文件编译成.o目标文件;
使用gcc命令加-shared参数将多个目录文件生成一个动态库文件;

注意Linux系统上默认的动态库名格式为:libxxx.so,其中xxx为生成库的名称。

案例演示1:

编写一个函数printHello,其功能为打印"Hello world"字符串,将其编译生成名为Hello的动态库,可以使用如下命令:

vim printHello.h
vim printHello.c
gcc -fPIC -c printHello.c -o printHello.o
gcc -shared  printHello.o -o libHello.so
 

使用vim编写printHello.h(申明printHello函数,方便以后被其它程序调用)
 

#ifndef __PRINTHELLO_H__
#define __PRINTHELLO_H__
#include <stdio.h>
void printHello();
#endif

使用vim编写printHello.c
 

#include <stdio.h>
void printHello()
{
    printf("Hello world\n");
}

[请在右侧“命令行”里直接体验]

使用动态库

动态库的使用方法与静态库使用方式略有不同,除了使用gcc中的-L-l参数外,想要调用动态库还需要更新Linux系统中/etc/ld.so.cache或者修改LD_LIBRARY_PATH环境变量,否则在运行程序的时候会报**"No such file or directory"**错误。

案例演示1:

调用以上案例生成的printHello函数,可以使用如下命令:

vim main.c
gcc main.c -o exe -L ./ -lHello
./exe

[使用vim编写程序]

[请在右侧“命令行”里直接体验]

此时编译正常,当运行的时候会报**"No such file or directory"**错误。

更新/etc/ld.so.cache来运行动态库
编辑/etc/ld.so.conf配置文件,然后加入需要加载的动态库目录。
运行ldconfig更新/etc/ld.so.cache

案例演示1:

更新/etc/ld.so.cache,然后运行上一个案例生成的exe,可以使用如下命令:

sudo vim /etc/ld.so.conf
sudo ldconfig
./exe

[使用vim/etc/ld.so.conf文件添加/home/fzm路径]

[请在右侧“命令行”里直接体验]

修改LD_LIBRARY_PATH环境变量

在运行可执行文件前修改LD_LIBRARY_PATH变量为可执行程序指定需要加载的动态库路径。

案例演示1:

修改LD_LIBRARY_PATH,然后运行上一个案例生成的exe,可以使用如下命令:

LD_LIBRARY_PATH=.  ./exe

[请在右侧“命令行”里直接体验]

注意

LD_LIBRARY_PATH告诉了exe程序现在当前目录下寻找链接的动态库;
当运行环境中同时存在同名的静态库和动态库时,默认优先链接动态库;

编程要求

本关任务是学会生成和使用动态库。

具体编程要求如下:

在当前目录下编写一个简单的函数int Sub(int a, int b),其功能为计算输入参数a-b的结果;

将Sub函数编译生成一个动态库libSub.so,并存放在当前目录下;

修改/etc/ld.so.conf,添加当前目录,并更新/etc/ld.so.cache

答案及其步骤: 
 
vim Sub.h

进入如下输入:
 

#include<stdio.h>
int Sub(int a,int b);

vim Sub.c

进入如下输入:

#include<stdio.h>
int Sub(int a,int b)
{
    return a-b;
}

gcc -fPIC -c Sub.c -o Sub.o
gcc -shared Sub.o -o libSub.so
vim main.c

进入如下输入:

#include "Sub.h"
int main()
{
    int c=Sub(1,1);
    return c;
}

gcc main.c -o exe -L ./ -lSub
vim /etc/ld.so.conf

进入如下输入:

/root    //输入/root


 

ldconfig
./exe

全部输入如下:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

el-menu 有一级二级三级菜单

效果如下 菜单代码如下 <el-menu:default-active"menuDefaultActive"class"el-menu-box":text-color"menuTextColor":active-text-color"menuActiveTextColor":unique-opened"true"><!-- 一级菜单 --><tem…

常见排序算法(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,计数排序,基数排序,桶排序)

一.排序的概念 1.排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作 2.稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排…

STM32 HAL库 利用CH376进行USB文件读写

STM32 其实可以进行读取USB文件,但仅限于F4以上芯片才可以进行SUB文件读写,但在项目开发中,往往用不到此芯片,那么只能通过外挂的USB芯片进行USB文件读写,本文则是采用STM32F103的SPI与CH376进行通信,通过CH376操作指令进行操作。 1、CH376介绍 CH376芯片 是沁恒的一款文…

paho-mqtt 库揭秘

文章目录 **paho-mqtt 库揭秘**第一部分&#xff1a;背景介绍第二部分&#xff1a;paho-mqtt 是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;库函数使用方法第五部分&#xff1a;场景应用第六部分&#xff1a;常见Bug及解决方案第七部…

如何批量给Word文件增加前缀序号?“汇帮批量重命名”帮助你批量给word文件增加前缀序号。

批量给Word文件增加前缀序号的过程&#xff0c;对于经常处理大量文档的人来说&#xff0c;是一项既繁琐又必要的任务。首先&#xff0c;我们需要明确为什么要给Word文件增加前缀序号。在很多情况下&#xff0c;当我们需要按照一定的顺序对多个文档进行管理和归档时&#xff0c;…

海绵结构:Hash as RO

参考文献&#xff1a; [BDPA07] Bertoni G, Daemen J, Peeters M, et al. Sponge functions[C]//ECRYPT hash workshop. 2007, 2007(9).[GPP11] Guo J, Peyrin T, Poschmann A. The PHOTON family of lightweight hash functions[C]//Advances in Cryptology–CRYPTO 2011: 31…

MBD_入门篇_19_Simulink数学运算模块

19.Simulink数学运算模块 19.1 概述 数学运算模块&#xff0c;包含了一些数学运算&#xff0c;比如最常用的加减乘除等。 19.2 Add加法模块 设置加法模块的形状&#xff0c;默认是方形的&#xff0c;推荐使用方形的。 运算符设置。 设置符号为-&#xff0c;可以理解为本来是0,…

CSS 设置空格原样显示 white-space:pre-wrap;

CSS 设置空格原样显示 问题描述 html 渲染内容时&#xff0c;对于 空格、回车、Tab 键的 默认处理方式是 &#xff1a; 无论存在多少个连续的空格&#xff0c;都只会保留一个。 结论 由于以上的特性&#xff0c;导致了我们无法直接渲染出原格式的文本。pre 标签 了解一下 &…

今日刷三题(day4):简写单词+dd爱框框+除2!

题目一&#xff1a;简写单词 题目描述&#xff1a; 比如 “College English Test”可以简写成“CET”&#xff0c;“Computer Science”可以简写为“CS”&#xff0c;“I am Bob”简写为“IAB” 输入输出描述&#xff1a; 输入&#xff1a;一个复合单词 输出&#xff1a;输…

20240330-1-词嵌入模型w2v+tf-idf

Word2Vector 1.什么是词嵌入模型&#xff1f; 把词映射为实数域向量的技术也叫词嵌⼊ 2.介绍一下Word2Vec 谷歌2013年提出的Word2Vec是目前最常用的词嵌入模型之一。Word2Vec实际是一种浅层的神经网络模型&#xff0c;它有两种网络结构&#xff0c;分别是连续词袋&#xff…

C++ stl容器stack,queue,priority_queue的底层模拟实现

目录 前言&#xff1a; 文档借鉴&#xff1a;Reference - C Reference 1.deque a.deque的结构特点&#xff1a; b.deque的迭代器结构&#xff1a; c.面试题&#xff1a; 2.stack 3.queue 4.仿函数 5.priority_queue 总结&#xff1a; 前言&#xff1a; 本篇一共简单…

Hive 中常用的函数以及数据类型

数据类型 1.基本数据类型: 数据类型大小范围示例TINYINT1byte-128 ~ 127100YSMALLINT2byte-32768 ~ 32767100SINT4byte-2^32~ 2^32-1100BIGINT8byte-2^64~ 2^64-1100LFLOAT4byte单精度浮点数5.21DOUBLE8byte双精度浮点数5.21DECIMAL-高精度浮点数DECIMAL(9,8)BOOLEAN-布尔型tr…

VF02 XBLNR增强将不可编辑状态改为可编辑状态

VF02 XBLNR增强将不可编辑状态改为可编辑状态 一、业务界面展示 二、在程序SAPMV60A的INCLUDE程序MV60AF0F_FELDAUSWAHL_SONDERREG增强 *$*$-Start: ZEN_POINT_TEST1---------------------------------------------------------------------$*$* ENHANCEMENT 1 ZFI_TEST01.…

C语言 | 自定义类型:联合和枚举

目录&#xff1a; ----前言 1. 联合体 1.1 联合体类型的声明 1.2 联合体的特点 1.3 相同成员的结构体和联合体对比 1.4 联合体大小的计算 1.5 联合的使用 1.6联合体的练习 2. 枚举 2.1 枚举类型的声明 2.2 枚举类型的优点 2.3 枚举类型的使用 --前言&#xff1a; c语言中内…

代码随想录刷题随记24-回溯

代码随想录刷题随记24-回溯 491. 非递减子序列 leetcode链接 与之前的集合问题不同&#xff0c;而本题求自增子序列&#xff0c;是不能对原数组进行排序的&#xff0c;排完序的数组都是自增子序列了。所以不能通过排序的问题去重 class Solution {List<List<Integer…

超越GPT-4V,苹果多模态大模型上新,神经形态计算加速MLLM(二)

上文介绍基于MINOnets神经网络架构加速多模态大模型的策略&#xff0c;本文将以Spinnaker2多核神经网络芯片EGRU架构为起点&#xff0c;覆盖存内计算架构&#xff0c;介绍新型计算架构在加速大模型推理的作用。SpiNNaker 2是一个设计用于大规模异步处理的多核神经形态芯片&…

建议收藏 | 2023年中国SCI期刊影响因子最新预测

公众号&#xff1a;生信漫谈&#xff0c;获取最新科研信息&#xff01; 2023年中国SCI期刊影响因子最新预测 经过Web of Science 官网对引用前50和IF排名前50的中国&#xff08;包括香港、澳门和台湾&#xff09;期刊以及中国主办或中国人主编的高影响力期刊进行了2023年影响…

数据结构_时间复杂度

✨✨所属专栏&#xff1a;数据结构✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 什么是时间复杂度&#xff1f; 时间复杂度的定义&#xff1a;在计算机科学中&#xff0c;算法的时间复杂度是一个函数&#xff0c;它定量描述了该算法的运行时间。一个算法执行所耗费的时间&#xff0…

YOLO世界:实时开放词汇对象检测

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;YOLO世界&#xff1a;实时开放词汇对象检测1、研究背景2、提出方法3、相关技术3.1、Re-parameterizable Vision-Language Path Ag…

MySQL中InnoDB存储引擎详细介绍

介绍 InnoDB是一种兼顾高可靠性高和高性能的通用存储引擎&#xff0c;在MySQL5.5之后&#xff0c;InnoDB是默认的MySQL存储引擎。 特点 DML(增删改)操作遵循ACID(事务四大特性)模型&#xff0c;支持事务&#xff1b;行级锁&#xff0c;提高并发访问性能支持外链FORELGN KEY约…