闲言少叙,直接切入主题。

一、Linux下的多文件编译(Ubuntu系统)。

对于小程序来说,往往一个.c文件就足够了,里面包含了各种主函数和功能函数,以及函数的声明等等。但是这样的弊端主要有两点,一是可读性较差,所有程序都在一个文件中造成检查和分析时候很不方便,特别是对于较大的工程来说,是无法想象的。第二点就是保密性,在工作中,我们要将程序交给客户,但是我们并不想让客户知道我们的源代码,所以要用这种方式将功能函数以.o的文件(二进制码)交给客户,确保自己的劳动成果不被别人剽窃,可以做到保护知识产权。

说明了缘由,接下来具体介绍多文件编译。一般我们将文件分为三类,第一类是.h的头文件,第二类是.c的主函数文件,第三类是.c的功能函数文件。头文件用来存放各种函数的声明,主函数是调用功能函数来实现工程需求,功能函数文件是用来存放各种实现各种功能模块的函数定义。

头文件的作用就是在预处理时候将头文件的内容放在有#include包含的地方。#include后面跟着的头文件有两种形式,一种是<>,一种是“”的形式,如:

#include<stdio.h>

#include"stdio.h"

第一种是去默认的目录去寻找该头文件,第二种是先在当前目录下去寻找该头文件,若当前目录没有,则去默认的目录去寻找。

在Ubuntu下用gcc进行多文件编译的命令形式是gcc main.c fun.c -o fun生成的fun就是编程出来的可执行文件。

二、extern和static

sxtern是修饰符,可以用来修饰变量或者函数。它的作用就是调用外源文件中定义的变量和函数。比如说我在a.c文件中定义了一个全局变量int hello = 0,那么我要是想在b.c文件中调用这个hello变量,那么我就可以在b文件要引用的地方声明extern int hello就可以在该作用域下使用hello这个变量了。这里需要注意的是extern int hello是声明这个变量,并不是定义这个变量,c语言不允许重载,所以不能重复定义。

static同样也是修饰符,用来修饰变量和函数。在用来修饰全局变量和函数时,他的作用和extern是相反的,static修饰的全局变量和函数是禁止外源文件调用,比如我在a.c文件中定义一个全局变量static int hello,那么我想在b.c文件中引用,我使用extern int hello,并且使用,程序在编译的时候会报错。

static在修饰局部变量时,会将该变量和全局变量一样存入静态存储区,他的生存周期和全局变量一样,一直到程序运行结束才被释放,但是该变量的作用域仍然是原来的作用域,比如一个变量是fun()函数中的一个局部变量,那么在函数调用结束后,该变量就不能使用,当再次调用该函数的时候,该局部变量任然是那个地址,,存储的还是那个值。

三、数组

首先,数组的本质是连续的内存。

数组就是开辟了一段连续的内存来存储相同类型的数据。int a[10]就是开辟了是个int型的空间来存储十个int型的数据,所以数组a占用的内存空间就是四十个字节。

数组的初始化可以分为全部初始化和部分初始化,数组也只有在初始化的时候才能全部赋值,初始化之后只能一个一个赋值或者采用字符串输入scanf(%s,a)的方式进行整体赋值。部分初始化时,没有得到数值的空间默认是0,是绝对的0,不是字符‘0’。这个0也就是‘\0'。说到这,就可以引用字符串数组的概念。字符串数组本质上也是数组,我们可以采用这个方式来初始化字符串数组:char a[10] = "abc",这种初始化等同于cha a[10] = {'a','b','c','\0'},可以看出,字符串数组的初始化会在结束时加一个’\0',在c语言中,字符串与连续字符的区别就在这里,字符串是通过最后的'\0'来判断该字符串是否结束,也就是说,'\0‘是字符串的结束标识符。当用%s输出字符串时,就是输出到'\0'为止,且'\0'不输出,统计字符串长度(strlen()函数)也是一样,'\0'不统计在内。在用scanf输入用%s的方式输入字符串时,会在敲下回车的时候结束字符串的输入,此时会在将字符串最后的那个字符后面加一个'\0'作为字符串的接鼠标识。而回车并不会存入字符串中去。

这里提一下二维数组,二维数组本质上和一维数组一样,都是连续的内存,只是二位数组就是将一维数组分段,然后二维数组的特点就是既可以方便的一个一个访问,也可以方便的一段一段访问。

数组中还有一个重要的概念就是数组名。如char a[ 10 ] = {0};a就是这个数组的数组名,她就代表了这个数组。可以将数组名a理解成一个指针常量,注意这里的常量,因为数组名并不占内存,仅仅是一个形式而已,所以a++这样的操作都是错误的,编译也是不会通过的。但是在用数组名访问里面的数组元素的时候,她又和指针一样,可以用解引用(*(a+i))访问,也可以用下标方式(a[i])访问,而且这两种方式是等同的。这里需要注意的是数组名在两种情况是比较特殊的,比如用sizeof(a)操作时,如果a是指针,那么得到的是4(32位系统)或者8(64位系统),而如果a是数组名的话,那么得到的是数组a占用的内存空间,这里是10,这是一种情况,而另一种情况是&a,照理来说a不占用内存,&a应该是空,但是c语言中将&a的操作认为是取数组a首元素的地址,&a的值和a的值是相等的,都是数组首元素的地址。

最后再讲一个字符指针,如char *p_char = "abc";这里的abc存储的位置是文字常量区,这个区域的特点就是只读,所以*p_char 是不能作为左值操作的,即不能赋值,不能改变。而普通的数组元素是储存在栈区,是可读写的。

这里提一下sizeof()和strlen()。sizeof()和strlen()是两个完全不一样的东西,sizeof是运算符,strlen()是函数,sizeof()中()内可以是数组(计算数组空间大小),函数(计算返回值类型的空间),类型(该类型所占的空间),对象(对象实际占用的空间)和指针(指针变量的空,一般为4(32位系统)或者8(64位系统))。而strlen()函数则是专门用作计算字符床长度的函数,她是以输入的首地址开始,到'\0'时该字符串所占的长度,'\0'并不计算在内。

四、函数

函数的本质是一个值,就是他的返回值。

函数的形式:返回值类型 函数名(参数列表){语句列表}函数可以没有返回值,那么前面的类型就是void。函数的本质就是一个值,只是他在实现的过程中也可以进行输入输出等完成一系列的功能。主函数也是一种函数,主函数的类型是int型,在c语言中,一般主函数用return 0来表示主函数运行正常。函数是模块化编程的一种体现,利用函数可以将复杂的工程分解成许多小的功能模块,分模块化实现。 函数在使用前要先声明,并且要有相应的定义。函数的声明放在头文件中,函数的定义则在相应的函数库文件中。

形参和实参:在定义函数时,函数的参数列表中的参数就是函数形参;调用函数时,在函数的()中放的参数就是实参。形参是局部变量,又叫临时变量,只有在函数被调用的时候才给他分配地址空间,在调用结束时候就收回,因此这个变量的生存周期就是该函数的运行周期,作用域就仅限于这个函数的范围。在函数被调用的时候,函数{}中的语句列表中的形参全部被实参替代,这就是形参和实参的关系。

函数的返回值只能有一个或者没有。所以在需要多个数据返回的时候怎么办?这里用了一个巧妙的办法,将函数的形参定为一个指针变量,然后再调用函数的时候,将需要的参数的地址放在参数列表中,这样就可以实现对个数值返回的效果了。

转载于:https://www.cnblogs.com/wangyouwei/p/5700620.html

Ubuntu的多文件编译以及c语言的数组、函数相关推荐

  1. 【C 语言】文件操作 ( 文件加密解密 | 使用第三方 DES 加密解密库 | 头文件导入 | 兼容 C++ 语言 | 加密解密函数说明 )

    文章目录 一.导入第三方库头文件 二.头文件说明 1.兼容 C++ 语言 2.头文件导入限制 3.加密解密函数说明 一.导入第三方库头文件 对文件进行加密 , 将文件中的数据分成若干块 , 一块一块的 ...

  2. C语言中的cbp文件是什么,C语言编程入门——函数(上)

    函数是结构化编程语言中最重要的组成部分,模块独立化的基本单位. 函数的声明: # include void f(void);//函数的声明,即声明f是一个函数. void g(void); void ...

  3. c语言字符串数组函数参数,C语言/C++ 数组作为函数参数

    前几天帮别人解决数组拼接问题(类似字符串拼接)时想到这个专题.因为她的代码太糟糕. 我们知道C.C++中的数组是没有拷贝(复制)运算的,除非编译器支持.因为C语言发明的初衷是替换汇编语言,要知道你用不 ...

  4. C语言自定义数组函数

    自定义数组函数 strcmp #include<stdio.h> int main() { int mystrcmp(char a[], char b[]); char str1[] = ...

  5. 如何用c语言return数组函数

    对于一维数组来说 就像下面这个例子,是这样一个题 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标.你可以假设每种输入 ...

  6. makefile:带你了解一种常用于GNU gcc编译的工具语言

    摘要:该文章主要介绍makefile,一种常用语GNU gcc编译的工具语言,同时LiteOS也是利用该文件对工程项目进行make构建生成执行文件的. LiteOS源码中使用makefile进行文件的 ...

  7. C语言 define 定义函数 - C语言零基础入门教程

    目录 一.define 简介 二.define 定义函数 1.define 定义不带参数的函数 2.define 定义带参数的函数 三.define 定义函数陷阱 1.define 函数陷阱一 2.d ...

  8. C语言 define 定义函数(多行书写) - C语言零基础入门教程

    目录 一.define 简介 二.define 定义多行函数 1.简单使用 2.经典案例 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 ...

  9. 在Ubuntu下编译运行C语言程序

    目录 实验题目 1 gcc编译 1.1 编译运行hello.c程序 1.1.1 使用vim创建hello.c文件 1.1.2 使用gcc将其转化为可执行文件 1.1.3 运行hello可执行文件 1. ...

最新文章

  1. oracle的parameters怎么用,oracle普通用户使用show parameter方法
  2. 预处理器命令必须作为第一个非空白空间启动_第三章 图形处理器(上)
  3. ROS的学习(五)在工作空间中构建和使用catkin包
  4. libxml主要函数说明 (一)
  5. dubbo接口调试工具
  6. ***【九度oj-1343】城际公路网
  7. MCGS实现按键按一次按下,再按一次弹起
  8. 大学生面试20个经典问题及回答思路
  9. Python转换excel文件,将xlsx文件转换为xls文件
  10. 【滤波专题-第3篇】IIR无限冲激响应和FIR有限冲激响应数字滤波器有什么区别?
  11. date.gettime()与时间的获取
  12. restTemplate实现 authorization basic权限认证(带账号密码)
  13. 微擎+微赞(微官网)100套精华模板完美完整版
  14. 格力(GREE)家用移动空调免安装一体机空调KY-23NK 清灰拆装教程
  15. 洛谷 P5266 【深基17.例6】学籍管理
  16. Marketo收购社交营销应用开发商Crowd Factory
  17. 12306网上购票进行身份核验的步骤
  18. 扫码枪多次扫码用空格分开
  19. Iverilog源码分析 -- VPI scope的实现
  20. 【笔记】《软件工程导论(第6版)》-张海藩、牟永敏

热门文章

  1. linux目录/etc/nc.d/nc.local开机启动项无效
  2. js获取前一天/后一天
  3. Android开发笔记(二)颜色的使用
  4. C语言去除字符串空格
  5. 删除 java代码中所有的注释
  6. android-清单小文件
  7. 今天开始写一些内容,留作备份。
  8. 第3章   IP寻址
  9. gprof 输出内容解释
  10. python人脸融合_用Python玩人脸融合,想知道你未来孩子的长相?(附代码)