C语言的一些杂货

好久不写C,发现以前自己踩过的坑,又会踩一遍。朦胧的感觉一直有,就下决心总结一下,以免再次犯傻了。

首先是编译问题。什么放在.c文件中,什么放在.h文件中?为什么要分开两个文件?编译的时候是怎么处理的?

从功能性的角度来看,把所有代码都放到一个大的.c文件中并没有什么不好,甚至还帮助编译器做了很多工作。为什么要非看不同的.c和.h文件是因为代码是给人看的,只有编译过后的那个可执行文件才是给机器用来执行的。看代码和看书是一样的道理,总希望有个相应的目录,把相同模块的内容集中在一起,这样做一来是可以方便人理解,二来是很多相同名字的概念不用再做区分了。一个合理的目录绝对是一本好书必备的,甚至写书的人就应该先想到目录的结构。

弄明白这个以后只要说明.c和.h里面内容的差别,就能够轻松的分辨什么内容要放到什么里面了。.h文件叫做头文件,顾名思义它是对应的.c文件的开头部分,也就是总的描述这个.c文件是干什么的。.h里面放的是.c文件中的函数的声明,一些变量的声明,一些宏定义,大量的注释。这样做的好处有比如说自己以前写的几个函数,放到了.c文件中,现在想知道这几个函数干什么用的,又不想再读一遍自己的代码,其实看看自己写的.h文件就差不多能回忆起个大概了。另一个好处是如果其他好几个.c文件都要用到这里面的函数,那么只要每个.c文件中都include这个.h文件就可以了。当然光光include是不够的,需要编译器来做一些其他工作,这个后面说。

现在说一下编译的过程,来理解.h和.c文件。如果我们只要编译一个.c和对应的.h文件,那么问题很简单,首先#include这句话就可以看做是把.h里的内容直接复制到.c中,然后编译器的工作就只针对这一个文件了。没什么好说的。关键是多个文件进行编译的时候,文件之间可能有依赖关系,举个例子,b.c里面用到了a.c里面的函数,main.c里面用到了a.c和b.c里面的函数。如下:

a.c b.c main.c
#include"a.h"
#include"a.h"

#include"b.h"


#include"main.h"

#include"a.h"

#include"b.h"

首先是include这句话的功能就是复制粘贴是不变的,也就是说a.h这个文件里的内容会出现在a.c,b.c,main.c中。但是没关系啊,因为里面都是函数的声明,重复声明同一个函数是不会出问题的,这和变量是一个道理,比如你连写10行int a; 最后也只是有一个a变量。编译的时候首先让编译器把a.c和a.h合起来进行编译,用gcc编译器的话命令是gcc a.c -c a.o 其中a.o是生成的中间文件并不是最终结果,同样的道理编译b.c和c.c,并生成相应的b.o和c.o文件。然后用编译器中的连接器把这些中间文件.o们连接起来生成最后的可执行文件。gcc的编译命令是gcc a.o b.o c.o -o test。这个test文件就可以运行了。

然后是指针问题

平时的工作中经常要用到多维数组,这里主要说明多维数组的函数间的参数传递问题。这里主要说的是C中的情况,C++中的指针问题可能会有更好的解决方法,比如说引用,在形式上会更好看。

首先要明白数组和指针是不同的变量类型,举个例子:int a[10]; 其中a的地址和&a的内存地址是相同的,但C中并不把它们当做相同的类型,a和&a[0]是对等的,可以直接赋值给一个int * 的指针。但如果把&a赋值给一个int *类型的指针的话,就会给一个警告warning: assignment from incompatible pointer type [enabled by default]。虽然由于它们的值相同这样做不会出现什么问题,但是能够看到它们是不同的。那么哪里会遇到问题呢?我遇到的问题是在用sizeof运算符的时候。sizeof(a)返回的应该是sizeof(int)*10,而sizeof(&a)返回的就是sizeof(void*)一个普通指针的大小。我的情形是想要在传递数组的时候,检测出数组的长度,这样就不用再传递一个数组长度的参数了。但事实上这在C里面是不可能的,因为sizeof的功能就是返回对象占用空间的大小,如果不是采用值复制的方式传递数组,必定只是传递了指针,那么指针所占用的空间一定是一个void*的大小。所以遇到类似的问题还是老老实实的再传一个参数吧。

另外想补充的一点是数组指针和指针数组的差别,比较懒,看到别人写的比较好,引用一下吧。

http://see.xidian.edu.cn/cpp/html/476.html

http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html

时间: 2024-12-30 11:59:42

C语言的一些杂货的相关文章

使用R语言计算均值,方差等

R语言对于数值计算很方便,最近用到了计算方差,标准差的功能,特记录. 数据准备 height <- c(6.00, 5.92, 5.58, 5.92) 1 计算均值 mean(height) [1] 5.855 2 计算中位数 median(height) [1] 5.92 3 计算标准差 sd(height) [1] 0.1871719 4 计算方差 var(height) [1] 0.03503333 5 计算两个变量之间的相关系数 cor(height,log(height)) [1] 0

GCC在C语言中内嵌汇编 asm __volatile__ 【转】

转自:http://blog.csdn.net/pbymw8iwm/article/details/8227839 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可, GCC会自动插入代码完成必要的操作. 1.简单的内嵌汇编 例: __asm__ __volatile__("hlt"); "__asm__"表示后面的

C语言轻松高效学习方法之:多种方法实现

多种方法实现同一个功能,可以调动你学的所有知识去做,有助于你学的融会贯通. 下面举例来看: 实现功能:求一个整数的位数: 实现语言:C语言: 开发环境:Visual Studio 2017 如:3215是4位数 实现原理: 3215/10 = 321 ----1位数 321/10 = 32 ----又是1位数 32/10 = 3 ----又是1位数 3/10 = 0 ----又是1位数 共4位数,且终止计算条件是/10结果为0的时候: 根据这个原理,先写一个最笨的原始方法: 效果: 这种实现方案

轻松学习C语言编程的秘诀:总结+灵感

目前在准备一套C语言的学习教程,所以我这里就以C语言编程的学习来讲.注意,讲的是"轻松学习",那种不注重方法,拼命玩命的方式也有其效果,但不是我提倡的.我讲究的是在方式方法对头.适合你.减轻你学习负担和心里压力的前提下,才适当的抓紧时间. 因此,探索一种很好的学习方法就是我所研究的主要内容. 众所周知,学习C语言并非易事,要学好它更是难上加难.这和你期末考试背会几个题目的答案考上满分没多大关系,也就是说你考试满分也说明不了你学好.学精通了C语言.那么怎么才算学精通C语言?闭着眼睛对自己

详解go语言的array和slice 【二】

上一篇  详解go语言的array和slice [一]已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制slice的容量,在操作新slice时,如果新slice的容量大于长度时,添加新元素依然后使源的相应元素改变.这一篇里我会讲解到如何避免这些问题,以及迭代.和做为方法参数方面的知识点. slice的长度和容量设置为同一个值 如果在创建新的slice时我们把

自动生成小学四则运算题目(C语言)

这个简易四则运算是我在百度上找的博主叫53余雅诗的一篇c语言代码,网址为http://www.cnblogs.com/ys1101/p/4368103.html,功能是可以选择加减乘除进行简易的四则运算,判断对错.我在VS2017上编译没有bug,因为功能只有整数运算,所以我在此基础上加了真分数的四则运算以及统计得分等,最后成功运行程序.我把我的源代码放在github上,地址为https://github.com/xiaofancheng/helloworld.

PAT 1009 说反话 C语言

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有多余的空格. 输出格式:每个测试用例的输出占一行,输出倒序后的句子. 输入样例: Hello World Here I Come 输出样例: Come I Here World Hello 1 #include<stdio.h> 2 #

PAT 1006 换个格式输出 C语言

让我们用字母B来表示"百".字母S表示"十",用"12...n"来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数.例如234应该被输出为BBSSS1234,因为它有2个"百".3个"十".以及个位的4. 输入格式:每个测试输入包含1个测试用例,给出正整数n(<1000). 输出格式:每个测试用例的输出占一行,用规定的格式输出n. 输入样例1: 234 输出样例1: BBSSS1

Go语言 IDE之Gogland配置使用

Gogland 是 JetBrains 公司推出的 Go 语言集成开发环境.Gogland 同样基于 IntelliJ 平台开发,支持 JetBrains 的插件体系.目前正式版尚未发布.官方:https://www.jetbrains.com/go/.关于使用,即将开始咯! 一.安装Golang 1) 首先到https://golang.org/dl/选择适合你系统的安装包,(墙内:http://golangtc.com/download). 2)下载完成安装到指定目录即可.我这里是(D:\G