我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C语言中链接器的示例分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C语言中链接器的示例分析

小编给大家分享一下C语言中链接器的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

      1 什么是链接器

      典型的链接器把由编译器或汇编器生成的若干个目标模块,整合成一个被称为载入模块或可执行文件的实体–该实体能够被操作系统直接执行。

      C语言中链接器的示例分析

      链接器通常把目标模块看成是由一组外部对象组成的。每个外部对象代表着机器内存中的某个部分,并通过一个外部名称来识别。因此,==程序中的每个函数和每个外部变量,如果没有被声明为static,就都是一个外部对象。==某些C编译器会对静态函数和静态变量的名称做一定改变,将它们也作为外部对象。由于经过了“名称修饰”,因此它们不会与其它源程序文件中的同名函数或同名变量发生命名冲突。

      2 声明与定义

      extern int a;

      上面的这段代码并不是对a的定义,而是说明a是一个外部整型变量。

      注意:引入之后,假如引入的位置在函数之外,就相当于在那个位置定义了全局变量,同样遵循局部变量优先原则,如果引入位置在某个函数之内,就相当于是一个局部变量,作用域与那个地方定义的局部变量相类似,此处讨论声明周期没有任何意义。

      int a;extern int a;

      上面的这两条语句既可以是在同一个源文件中,也可以位于程序的不同源文件之中。

      ==注意:每个外部变量只能定义一次。==如果外部变量的多个定义各指定一个初始值,例如:

      int a = 7;

      出现在一个源文件中,而

      int a = 9;

      出现在另一个源文件中,大多数系统都会拒绝接收该程序。但是,如果一个外部变量在多个源文件中定义却没有指定初始值,那么**某些系统会接受这个程序,而另外一些系统则不会接受。**所以,每个外部变量必须只定义一次。

      3 命名冲突

      3.1 命名冲突

      如果在两个不同的源文件中都包括了定义

      int a;

      那么它要么表示程序错误(如果链接器进制外部变量重复命名的话),要么在两个源文件中共享a的同一个实例(无论两个源文件中的外部变量是否应该被共享)。即使其中a的一个定义是出现在系统提供的库文件中,也仍然进行同样的处理。

      3.2 static修饰符

      static int a;

      static修饰a之后,a的作用域将被限制在一个源文件中,对于其它源文件,a是不可见的,且无法再被extern所引用,当然,static也适用于函数。使用static之后,我们就可以在其它的源文件中定义和这个已经被static修饰后的同名的变量或者函数。

      4 形参、实参、返回值

      如果我们使用的函数并未进行声明,但是已经在后面进行了定义,此时会默认函数返回类型为int型,这会造成极其严重的后果。

      使用的函数如果在使用之前并未定义或者可能在其他的文件中,那么就要进行声明,函数声明的目的就是告知编译器函数的返回值的类型。

      注意:如果一个函数没有float、short、或者char类型的参数,在函数声明中完全可以省略掉参数类型的说明(注意,函数定义中不能省略参数类型的说明)。这种做法依赖于调用者能够提供数目正确且类型恰当的实参。这里,“恰当”并不意味着“等同”:float类型的参数会自动转换为double类型,short或者char类型的参数会自动转换为int类型。

      在ANSI C标准发布之前,常常会有下面的这种声明和定义函数的方式:

      int isvowel();//声明函数的方式int isvowel(c)char c;{return c =='a' ;}

      实际上,上面这种写法与下面这种写法是等价的:

      int isvowel(int i){char c;return c=='a';}

      上述两种方式在VS2019中都是支持的。

      看下面的例子:

      #include<stdio.h>int main(){int i;char c;for (i = 0; i < 5; i++){scanf("%d", &c);printf("%d ", i);}printf("\n");return 0;}

      表面上,这个程序从标准输入设备读入5个数,在标准输出设备设备上写5个数:

      0 1 2 3 4

      实际上,这个程序并不一定得到上面的结果。例如,在某个编译器上,它的输出是(当然,在VS2019环境下程序会崩溃,因为非法修改了内存空间)

      0 0 0 0 0 1 2 3 4

      为什么呢?问题的关键在于,这里的c被声明为char类型,而不是int类型。如果程序要求scanf读入一个整数,应该传递给他一个指向整数的指针。而程序中scanf函数得到的却是一个指向字符的指针,scanf函数并不能分辨这种情况,它只是将这个指向字符的指针作为指向整数的指针而接受,并且在指针指向的位置存储一个整数。因为整数所占的存储空间要大于字符所占的存储空间,所以字符c附近的内存被覆盖。

      字符c附近的内存中存储的内容是由编译器决定的,在本例中它所存放的是整数i的低端部分。因此,每次读入一个数值到c时,都会将i的低端部分覆盖为0,而i的高端部分本来就是0,相当于i每次被重新设置为0,循环将一直进行。当到达文件的结束位置后,scanf函数不再试图读入新的值到c。这时,i才可以正常的运行,最后终止循环。

      5 检查外部类型

      注意:保证一个特定类型的所有外部定义在每个目标模块中都有相同的类型,“相同的类型”也应该是严格意义上的相同。

      例如,在一个文件中包含定义:

      char filename[] = "/etc/passwd";

      而在另一个文件中包含声明:

      extern char *filename;

      在定义时,filename是一个字符数组的名称。尽管在一个语句中引用filename的值将得到指向该数组起始元素的指针,但是filename的类型是”字符数组“,而不是字符指针。在第二个声明中,filename被确定为一个指针。这两种方式使用存储空间的方式是不同的,它们无法以一种合乎情理的方式共存。第一个例子字符数组filename的内存布局如下图所示:

      C语言中链接器的示例分析

      第二种方式字符指针filename的内存布局如下图所示:

      C语言中链接器的示例分析

      修改方法如下图所示:

      char filename[] = "/etc/passwd";extern char filename[];

      也可以这样进行修改:

      char*filename = "/etc/passwd";extern char *filename;

      6 头文件

      注意:每个外部对象只在一个地方声明,这个声明的地方一般就在头文件种,需要用到该外部对象的所有模块也应该 包括在这个头文件。特别指出的是,定义该外部对象的模块也应该包括这个头文件。

      以上是“C语言中链接器的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

      免责声明:

      ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

      ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

      C语言中链接器的示例分析

      下载Word文档到电脑,方便收藏和打印~

      下载Word文档

      猜你喜欢

      C语言中链接器的示例分析

      小编给大家分享一下C语言中链接器的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1 什么是链接器典型的链接器把由编译器或汇编器生成的若干个目标模块,整合成
      2023-06-29

      C语言中单链表的示例分析

      这篇文章将为大家详细讲解有关C语言中单链表的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、思路步骤1. 定义结构体a.数据域:用来存放数据b.指针域:用来存放下一个数据的位置2.初始化申请头结
      2023-06-25

      C语言中队列的示例分析

      这篇文章将为大家详细讲解有关C语言中队列的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、队列(Queue)0x00 队列的概念???? 概念:① 队列只允许在一端进行插入数据操作,在另一端进行
      2023-06-29

      C语言中循环的示例分析

      这篇文章主要为大家展示了“C语言中循环的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言中循环的示例分析”这篇文章吧。(壹)while语句1.1while的执行流程比如我们实现:在屏
      2023-06-29

      C语言中数组的示例分析

      这篇文章给大家分享的是有关C语言中数组的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1. 数组数组是一组相同类型变量的有序集合,用于存放一组相同类型的数据。这一组变量用数组名和从0开始的下标标识,使用内
      2023-06-29

      C语言单链表实例分析

      今天小编给大家分享一下C语言单链表实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1、移除链表元素链接直达:移除链表元
      2023-06-30

      C语言中预处理的示例分析

      小编给大家分享一下C语言中预处理的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!#define定义宏带副作用的宏参数我们来看如下一段代码结果分别为12,1
      2023-06-25

      C语言中库函数的示例分析

      这篇文章主要为大家展示了“C语言中库函数的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言中库函数的示例分析”这篇文章吧。1 返回整数的getchar函数代码:#include
      2023-06-29

      C语言中二叉树的示例分析

      这篇文章主要为大家展示了“C语言中二叉树的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言中二叉树的示例分析”这篇文章吧。树概念及结构树是一种 非线性 的数据结构,它是由 n ( n
      2023-06-29

      C语言中冒泡排序的示例分析

      这篇文章给大家分享的是有关C语言中冒泡排序的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。(壹)冒泡排序1.1冒泡排序的设计冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排
      2023-06-29

      C语言中数据类型的示例分析

      这篇文章将为大家详细讲解有关C语言中数据类型的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。(壹) 数据类型介绍前面我们已经学习了基本的内置类型,以及他们所占存储空间的大小。:类型的意义: 使用这
      2023-06-29

      C语言中数据存储的示例分析

      这篇文章主要介绍了C语言中数据存储的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。(壹)大端小端藏端倪1.1 什么是大端小端大端(存储)模式,是指数据的低位保存在内
      2023-06-29

      C语言中动态内存的示例分析

      这篇文章主要为大家展示了“C语言中动态内存的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言中动态内存的示例分析”这篇文章吧。1.关于动态内存的函数1.1 malloc和free函数
      2023-06-29

      C语言中函数递归的示例分析

      这篇文章主要介绍C语言中函数递归的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!什么是递归?递归(recursion):程序调用自身的一种编程技巧。如何理解函数递归:1.从调用自身层面:函数递归就是函数自己调
      2023-06-29

      linux硬链接和软链接的示例分析

      这篇文章主要介绍linux硬链接和软链接的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言最近前端包管理器pnpm真的是太火了,大量的文章分析了pnpm的原理。了解之后,发现pnpm整个架构都是基于硬链接和
      2023-06-29

      C语言操作符的示例分析

      这篇文章给大家分享的是有关C语言操作符的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言C语言中操作符不多,但是有些相同的操作符都是在不同的表达式中,有不同的解释意思,比如 * 号,在表达式中5*5表示
      2023-06-20

      Linux下软链接和硬链接的示例分析

      这篇文章主要介绍了Linux下软链接和硬链接的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.Linux链接概念Linux链接分两种,一种被称为硬链接(Hard L
      2023-06-16

      C语言中字符串相乘的示例分析

      这篇文章主要介绍C语言中字符串相乘的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一. 分析思路示例:我们把每一个数都看成是一个字符串,每一个元素为十进制数字所对应的字 符,由于是后面的元素先进行运算,故我们
      2023-06-29

      c语言中移位运算符的示例分析

      这篇文章主要介绍c语言中移位运算符的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!C语言是什么C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发,使用C语言可以以简易的方式编译、处理低级存储
      2023-06-15

      编程热搜

      • Python 学习之路 - Python
        一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
        Python 学习之路 - Python
      • chatgpt的中文全称是什么
        chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
        chatgpt的中文全称是什么
      • C/C++中extern函数使用详解
      • C/C++可变参数的使用
        可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
        C/C++可变参数的使用
      • css样式文件该放在哪里
      • php中数组下标必须是连续的吗
      • Python 3 教程
        Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
        Python 3 教程
      • Python pip包管理
        一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
        Python pip包管理
      • ubuntu如何重新编译内核
      • 改善Java代码之慎用java动态编译

      目录