文档章节

链接多个文件

大道无名
 大道无名
发布于 2016/10/20 21:46
字数 1091
阅读 36
收藏 0

链接多个文件

在一个文件中可能需要引用另外一个文件中定义的全局变量或函数。

下面的例子是一个简单的数组操作程序,在operate.c文件中,定义了一个全局变量的数组和 一些数组操作。

#include <stdio.h>

#define MAX 5

int array[MAX] = {2, 7, 6, 4, 8};

//求和
int sum()
{
  int i;
  int n;
  n = 0;
  for(i = 0; i < MAX; i++) {
    n += array[i];
  }
  return n;
}

//得到数组中最大的元素
int get_max()
{
  int max;
  int i;
  i= 0;
  max = array[i];
  for(i = 0; i < MAX; i++) {
    if(array[i] > MAX){
      max = array[i];
    }
  }
  return max;
}

//输出数组中每个元素的值
void print()
{
  int i;
  for(i = 0; i < MAX; i++){
    printf("array[%d] : %d\n", i+1, array[i]);
  }
}

在main函数中使用:

#include <stdio.h>

extern int array[];   //导出全局变量的声明
extern int sum();     //导出函数的声明
extern int get_max();
extern void print();

int main(void)
{
  int all, max;
  all = sum();
  max = get_max();
  print();
  printf("the sum is %d, the max is %d\n", all, max);
  return 0;
}

运行结果如下:

array[1] : 2
array[2] : 7
array[3] : 6
array[4] : 4
array[5] : 8
the sum is 27, the max is 8

链接时符号解析规则 首先看两个概念:

  • 声明:表示告知编译器该变量的存在 如:int a;
  • 定义:不仅告知变量的存在,而且为该变量赋值,并分配内存空间 如:int a = 1;

当该变量的作用域内只有声明,而没有该变量的定义时,编译器会自动将第一个声明认为是 变量的定义,如下:

{
  //在这里声明变量b,由于在 该函数内找不到对变量b的定义
  //因此该声明被认为是变量的定义,这时分配了4个姊jie妹存储空间给b
  int b;
  b = 2;  //这是对变量b的赋值,不是定义
  return a + b;
}

C语言中的符号解析规则如下;

  1. 不允许有多个符号的定义,这里的符号指的是变量或者函数。
  2. 如果有一个符号定义和多个符号的声明,则选择被定义的符号。
  3. 如果有多个符号的声明,则从其中任选一个作为符号的定义。

链接规则的应用

实例1:

a.c中包含一个全局变量a的定义

#include <stdio.h>

int a = 123;  //一个全局变量

int main(void)
{
  return 0;
}

b.c中也包含一个全局变量的定义

int a = 321;  //同名的全局变量

void f(void)
{
  printf("function %f\n");
}

该例会造成链接错误,原因是两个文件中都对一个变量进行了定义,违反了第一条规则。

实例2

a.c中包含一个全局变量a的定义

#include <stdio.h>

void f(void); //函数的声明

int a = 123;  //全局变量的定义

int main(void)
{
  f();  //调用函数
  printf("a = %d\n", a);  //输出全局变量
  return 0;
}

b.c中包含一个全局变量a的声明:

int a;  //全局变量的声明

void f()
{
  a = 121;  //对全局变量赋值
}

由于两个源文件中出现了对变量a的定义和声明,因此其符号解析符合第二条规则,所以全 局变量a在f()中被修改为121. 输出为:a = 121

实例3

a.c中包含全局变量a定义

#include <stdio.h>

void f(void); //函数的声明

int a = 123;  //全局变量的定义
int b = 321;

int main(void)
{
  f();  //调用函数
  printf("a = %d, b = %d\n", a, b);  //输出变量a和b
  return 0;
}

b.c中包含对全局变量a的声明

double a;  //全局变量的声明

void f()
{
  a = 0.0;  //对变量a赋值
}

运行结果为: a = 0, b = 0

这是为什么(⊙o⊙)? 两个源文件分别包含全局变量a的定义和全局变量a的声明,根据第二条规则,不会出现链接错误,编译器会选择符号的定义。这时b.c中函数f()内对变量a的操作实际上操作的是a.c中的全局变量a。所不同的是由于在b.c总声明的变量为双精度型,所以对该变量进行赋值为0.0时,需要将由a所指向的内存空间的首地址开始的8个字节清0,而不是4个。这个时候,变量a后面的变量b的存储空间也被覆盖了。因此输出的a和b的值都是0.

© 著作权归作者所有

大道无名
粉丝 29
博文 161
码字总数 96019
作品 0
宣城
程序员
私信 提问
Linux磁盘和文件系统管理(6)_链接文件 ln

文件系统上的链接文件: hard link 硬链接: 多个路径指向同一个inode 当指向一个inode的多个路径时,创建文件的硬链接时会增加inode的引用计数; 当删除硬链接时,仅是删除一个访问路径,文...

xjxiaolei
2015/09/15
0
0
好程序员web前端分享CSS文件引用的最优方法

好程序员web前端分享CSS文件引用的最优方法,在html总引入css文件的方法: 1链接式: 2导入式:   区别:   使用链接式时,会在加载页面主体部分之前加载css文件,这样现实出来的页面一开...

好程序员IT
04/11
0
0
Linux系统的硬连接和软连接

硬链接与软链接是 Linux 文件系统中的一个重要概念,其涉及文件系统中的索引节点 (index node 又称 inode),而索引节点对象是 Linux 虚拟文件系统 (VFS) 的四个基本概念之一。 1、硬连接 为解...

笨拙的小Q
2016/07/07
26
0
Linux基础系列(四)Linux系统软链接硬链接知识

软链接 软链接(Soft Link)也称为符号链接(SymbolicLink)。Linux里的软链接文件就类似与Windows系统中的快捷键方式。Linux里的软链接文件实际上是一个特殊的文件,文件类型是l。软链接文件实际...

Bgxuliangwei
2015/08/13
0
0
Linux-静态链接库和动态链接库

博文说明【前言】: 本文将通过个人口吻介绍Linux中静态链接库和动态链接库相关知识,在目前时间点【2017年6月14号】下,所掌握的技术水平有限,可能会存在不少知识理解不够深入或全面,望大...

1清风揽月1
2017/06/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

【JavaScript】callee 与 caller

callee callee是函数参数arguments对象的一个属性,它指向参数arguments对象所在的函数自身。 function foo (x) {console.log(arguments.callee);return x;}foo(); 从控制台中可以看...

小草先森
29分钟前
2
0
全面剖析 Knative Eventing 0.6 版本新特性

摘要: Knative Eventing 0.6 版本已经于5月15号正式发布。相比于0.5版本,此次发布包含了一些重要特性及更新。针对这些新特性以及更新,我们如何快速、精准的定位主要技术点。本篇文章针对这...

阿里云云栖社区
31分钟前
9
0
ffmpeg常用命令

1.合并两个或多个视频文件 将a.flv b.flv合并为c.flv 编辑文件flvs.txt file 'a.flv'file 'b.flv' #ffmpeg -f concat -i flvs.txt -c copy c.flv...

硅谷课堂
32分钟前
1
0
MySQL面试题--常见的四种隔离级别

什么是事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个...

寰宇01
32分钟前
2
0
Docker 安装 reids

0、mac上安装docker brew cask install docker 1、查询reidis docker search redis 2、拉取redis最新版本(也可以拉取指定版本,如:docker pull redis:4.0) docker pull redis 3、查看镜像 ...

moon888
40分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部