【Linux操作系统】编译过程中遇到的问题-为什么加-c?执行文件提示无法执行二进制文件?main函数参数argc和*argv[]的作用和理解?

news2024/10/6 11:15:04

在使用GCC编译器进行程序开发时,我们经常会遇到一些编译过程中的问题, 比如为什么要加上"-c"选项,以及为什么生成的可执行文件无法执行等问题。
本篇博客将详细介绍这些问题,并给出相应的代码和解释,帮助读者更好地理解GCC编译过程中的"-c"选项和main函数的参数argc和*argv[]。
在这里插入图片描述

文章目录

    • 1. 为什么要加-c,-o?各元素表示什么关系
      • 1.1 一个完整编译命令各元素的解释
      • 1.2 gcc其他的选项
    • 2. 为什么报错“无法执行二进制文件,可执行文件格式错误”
      • 2.1 报错的普遍原因
      • 2.2 编译时带上-c的作用
    • 3.main函数带上argc和*argv[]两个参数的作用
    • 结论:

1. 为什么要加-c,-o?各元素表示什么关系

1.1 一个完整编译命令各元素的解释

我们使用一个例子说明:

gcc -c hello.c -o hello

里面每个元素的含义:

  • "gcc":是GNU编译器套装(GCC)的命令行工具。
  • "-c":是GCC的一个编译选项,表示只进行编译而不进行链接。使用该选项会生成一个目标文件(.o文件),而不是可执行文件。
  • "hello.c":是要编译的源文件的名称。这里的"hello.c"是一个示例文件名,可以替换为实际的源文件名。
  • "-o":是GCC的一个选项,用于指定输出文件的名称。
  • "hello":是输出文件的名称。这里的"hello"是一个示例文件名,可以替换为实际的输出文件名。

综合起来,命令"gcc -c hello.c -o hello"的含义是:

使用GCC编译器对名为"hello.c"的源文件进行编译,生成一个目标文件,并将该目标文件命名为"hello"。
注意,该命令只进行编译而不进行链接,因此生成的文件不是可执行文件,而是目标文件。如果想要生成可执行文件,可以去掉"-c"选项,即使用命令"gcc hello.c -o hello"。 这就是你的程序明明代码是对的,但是运行的时候报错的原因。
GCC(GNU Compiler Collection)是一套由GNU开发的编译器工具集,用于编译C、C++、Objective-C、Fortran、Ada等多种编程语言。

据此我们可以学习 g c c 其他的选项: \color{red}{据此我们可以学习gcc其他的选项:} 据此我们可以学习gcc其他的选项:

1.2 gcc其他的选项

  1. -c:只编译源文件,生成目标文件,不进行链接。
  2. -o :指定输出文件的名称。
  3. -g:在目标文件中生成调试信息,以便进行调试。
  4. -O:指定优化级别。例如,-O0表示不进行优化,-O1表示基本优化,-O2表示更高级别的优化。
  5. -Wall:显示所有警告信息。
  6. -Werror:将所有警告视为错误。
  7. -I < dir >:指定头文件的搜索路径。
  8. -L < dir >:指定库文件的搜索路径。
  9. -l :链接时使用的库文件。
  10. -D :定义宏。
  11. -E:只进行预处理,生成预处理后的源代码。
  12. -S:只进行编译,生成汇编代码。
  13. -shared:生成共享库文件。
  14. -static:生成静态链接的可执行文件。
  15. -pthread:链接多线程库。

2. 为什么报错“无法执行二进制文件,可执行文件格式错误”

2.1 报错的普遍原因

原因可能有以下几种: \color{red}{原因可能有以下几种:} 原因可能有以下几种:

  • 缺少可执行权限:使用"chmod +x <filename>"命令为文件添加可执行权限。
  • 编译时未加上"-o"选项指定输出文件名:确保在编译时使用了"-o"选项,并指定了输出文件名。
  • 编译时未加上"-c"选项:如果只进行了编译而没有进行链接,生成的目标文件无法直接执行。需要在编译时加上"-c"选项来只生成目标文件,然后进行链接操作生成可执行文件。

一般都是编译的时候带了-c的参数,导致没有进行链接,无法执行,那为什么要带上-c选项呢?

2.2 编译时带上-c的作用

GCC编译器提供了"-c"选项,用于只进行编译而不进行链接。这样做的好处是可以提高编译速度和灵活性。在大型项目中,当我们只对部分源文件进行更改时,只需要重新编译这些源文件,而不需要重新链接整个项目。下面是一个示例代码:

// main.c
#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(10, 20);
    printf("Result: %d\n", result);
    return 0;
}

假设我们对add函数进行了修改,我们只需要重新编译main.c文件即可:

gcc -c main.c

这样会生成一个名为main.o的目标文件,然后我们可以将其与其他目标文件进行链接,生成最终的可执行文件。

3.main函数带上argc和*argv[]两个参数的作用

在C语言中,main函数是程序的入口函数,它可以接受命令行传递的参数。main函数的参数有两个:argc和*argv[]。

  • argc(argument count) 是一个整数,表示命令行参数的数量。它包括程序本身的名称作为第一个参数。
  • *argv[](argument vector) 是一个指向指针数组的指针,其中每个指针指向一个命令行参数的字符串。argv[0]指向程序的名称,argv[1]指向第一个命令行参数,以此类推。

通过使用这两个参数,我们可以在程序中获取和处理命令行传递的参数。下面是一个示例代码:

// main.c
#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Number of arguments: %d\n", argc);
    printf("Program name: %s\n", argv[0]);
    
    for (int i = 1; i < argc; i++) {
        printf("Argument %d: %s\n", i, argv[i]);
    }
    
    return 0;
}

假设我们在命令行中执行以下命令:

./main arg1 arg2 arg3

输出结果将会是:

Number of arguments: 4
Program name: ./main
Argument 1: arg1
Argument 2: arg2
Argument 3: arg3

通过使用argc*argv[],我们可以根据不同的命令行参数执行不同的操作,从而实现程序的灵活性。

结论:

本篇博客详细介绍了GCC编译过程中的"-c"选项和main函数的参数argc*argv[]的作用和理解。通过加上"-c"选项,我们可以只进行编译而不进行链接,提高编译速度和灵活性。同时,我们还了解了main函数参数argc*argv[]的作用,以及如何在程序中获取和处理命令行传递的参数。

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

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

相关文章

Vue编写表单常用操作(过滤和排序)

目录 HTML代码&#xff1a; js代码&#xff1a; 效果展示&#xff1a; 此次的编写代码可以直接使用 HTML代码&#xff1a; <body><div id"app"><div v-for"(value,key) in person">{{key}}--{{value}}</div><div>商品名…

NXP的官方提供的EB工具license到期后怎么续期

前安装NXP官方提供的EB工具&#xff0c;license到期了。本以为不能在试用了&#xff0c;后来在官网找了一下&#xff0c;原来是可以继续的。 小记如下&#xff1a; 我使用的是29.0版本&#xff0c; 在官网找到这个版本的EB下载位置&#xff0c;红框框里就是可以使用的…

C++ primer 1.2 练习

练习1.3:编写程序&#xff0c;在标准输出上打印Hello,World。 C语言&#xff1a; #include <iostream> using namespace std; int main() {cout << "Hello World!"; } 练习1.4:我们的程序使用加法运算符来将两个数相加。编写程序使用乘法运算符*,来打印…

vue 10 axios,promise

01.axios是干啥的 说到axios我们就不得不说下Ajax。 在旧浏览器页面在向服务器请求数据时&#xff0c;因为返回的是整个页面的数据&#xff0c;页面都会强制刷新一下&#xff0c;这对于用户来讲并不是很友好。并且我们只是需要修改页面的部分数据&#xff0c;但是从服务器端发送…

HTTP--Request详解

请求消息数据格式 请求行 请求方式 请求url 请求协议/版本 GET /login.html HTTP/1.1 请求头 客户端浏览器告诉服务器一些信息 请求头名称: 请求头值 常见的请求头&#xff1a; User-Agent&#xff1a;浏览器告诉服务器&#xff0c;我访问你使用的浏览器版本信息 可…

Python学习笔记_基础篇(一)_初识python

Python简介 python的创始人为吉多范罗苏姆&#xff08;Guido van Rossum&#xff09;。1989年的圣诞节期间&#xff0c;吉多范罗苏姆为了在阿姆斯特丹打发时间&#xff0c;决心开发一个新的脚本解释程序&#xff0c;作为ABC语言的一种继承。 Python和其他语言的对比&#xff…

【左神算法刷题班】第17节:在有序二维数组中查找目标值、等于目标字符串的子序列个数

第17节 题目1&#xff1a;在有序二维数组中查找目标值 给定一个每一行有序、每一列也有序&#xff0c;整体可能无序的二维数组 再给定一个数num&#xff0c; 返回二维数组中有没有num这个数 例子 数组如下&#xff0c;找 6 是否存在。 1 3 5 7 2 4 6 13 3 9 14 …

穿越数字奇境:探寻元宇宙中的科技奇迹

随着科技的迅速发展&#xff0c;元宇宙正逐渐成为一个备受关注的话题&#xff0c;它不仅是虚拟现实的延伸&#xff0c;更是将现实世界与数字世界融合的未来典范。在这个神秘而充满活力的数字奇境中&#xff0c;涉及了众多领域和技术&#xff0c;为我们呈现出了一个无限的创新和…

【LeetCode75】第二十九题 删除链表的中间节点

目录 题目&#xff1a; 示例; 分析: 代码: 题目&#xff1a; 示例; 分析: 给我们一个链表&#xff0c;让我们把链表中间的节点删了。 那么最直观最基础的办法是遍历两边链表&#xff0c;第一遍拿到链表长度&#xff0c;第二次把链表中间节点删了。 这个暴力做法我没事过…

深入探究QCheckBox的三种状态及其用法

文章目录 引言&#xff1a;三种状态一、未选中状态&#xff08;0&#xff09;&#xff1a;二、选中状态&#xff08;2&#xff09;&#xff1a;三、部分选中状态&#xff08;1&#xff09;&#xff1a; 判断方法结论&#xff1a; 引言&#xff1a; QCheckBox是Qt框架中常用的复…

网络安全攻防实战:探索互联网发展史

大家好&#xff0c;我是沐尘而生。 互联网发展史&#xff1a;数字世界的壮阔画卷 从早期的ARPANET到今天的万物互联&#xff0c;互联网经历了漫长的发展过程。然而&#xff0c;随着技术的进步&#xff0c;网络安全问题也随之而来。我们不仅要探索互联网的壮阔历程&#xff0c;…

学习笔记整理-面向对象-05-内置对象

一、内置对象 1. 什么是包装类 Number()、String()和Boolean()分别是数字、字符串、布尔值的"包装类"。包装类的目的就是为了让基本类型值可以从它们的构造函数的prototype上获得方法。Number()、String()和Boolean()的实例都是object类型&#xff0c;它们的Primit…

e6zzseo:谷歌SEO如何建站

​​​​​​​#秋实之美#谷歌SEO是指优化网站以在谷歌搜索引擎上获得更好的排名和可见性。建立一个优化的网站需要考虑多个因素&#xff0c;包括网站结构、内容质量、关键词优化、技术优化等。 e6zzseo专注搜索引擎获客技术 以下是建立谷歌SEO友好的网站的一些建议&#xff1…

【springmvc系】利用RequestBodyAdviceAdapter做接口鉴权

需求 有个简单的需求&#xff0c;对于第三方接口我们需要做个简单的鉴权机制&#xff0c;这边使用的是非对称性加密的机制。我们提供三方公钥&#xff0c;他们通过公钥对接口json报文使用加密后的报文请求&#xff0c;我们通过对接收过来的请求某一个加密报文字段来进行RSA解密…

SpringBoot复习:(50)TransactionManager是哪里来的?是什么类型的?

运行结果&#xff1a; 可见它的类型是DataSourceTransactionManager.它是通过自动配置创建的。

iview中table表头内容换行展示

如图效果图展示表头内容换行展示&#xff0c;代码如下&#xff1a; 在data中定义表头column Columns:[ {title: this.labelFn(Name, Name),key: name,align: center,}, ]在methods中定义方法 labelFn (name, str) {// 在需要换行的地方加入换行符 \n &#xff0c;在搭配最底…

去掉数组中头部和尾部的0numpy.trim_zeros()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 去掉数组中头部和尾部的0 numpy.trim_zeros() 选择题 以下说法错误的是? import numpy as np anp.array([0,0,1,2,3,4,0,0]) print("【显示】a:");print(a) print("【执行1】p…

CSAPP Lec01

1. CMU 15213_15513 CSAPP 深入理解计算机系统 Lecture 01 Course Overview 中英字幕_哔哩哔哩_bilibili 从这个课程中可以学到什么&#xff1f;&#xff08;为什么要学这门课&#xff09; Great Reality #1&#xff08;数字类型&#xff09;: Ints are not Integers, Floats…

c语言——颠倒字符串顺序

//颠倒字符串顺序 //列如&#xff1a;我们将runningman利用递归翻转计算。 #include<stdio.h> void reverseSentence(); int main() {printf("字符串输入:");reverseSentence();return 0; }void reverseSentence() {char c;scanf("%c",&c);if(c!…

Java课题笔记~ JSP开发模型

MVC 1.JSP演化历史 1. 早期只有servlet&#xff0c;只能使用response输出标签数据&#xff0c;非常麻烦 2. 后来有了jsp&#xff0c;简化了Servlet的开发&#xff0c;如果过度使用jsp&#xff0c;在jsp中即写大量的java代码&#xff0c;有写html表&#xff0c;造成难于维护&…