免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 10665 | 回复: 21
打印 上一主题 下一主题

[C] 头文件和源文件的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-07-27 12:43 |只看该作者 |倒序浏览
大家好:
          我遇到一个问题突然不太清晰,就是说头文件和源文件的问题。
          为了搞清楚之间的关系,我写了三个文件,分别为and.h and.c main.c
//and.h
int and(int, int);

//main.c
#include "and.h"
#include <stdio.h>
int main(void)
{
        int a, b, c;
       
        printf("lease Input a , b:\n";
        scanf("%d %d",&a, &b);
        c = and(a, b);
        printf("The Result is %d\n", c);
        return 0;
}

//and.c
int and(int a, int b)
{
        int c;
        c = a + b;
        return c;
}

当使用gcc main.c and.c -o main,毫无疑问可以正确编译出想要的结果。
1.但是实际上没写#include "and.h",也是可以编译的,我并没有在main函数声明这个函数,请问这是为什么,我看过一个帖子说用头文件声明的函数默认是以extern方式声明的,但是我在使用之前并没有声明,为何也可以正确编译,这样头文件的声明的意义好像就没有了,不知道我错在哪里?
2.我使用gcc -c and.c -o and.o, ar -rs liband.a and.o,将OBJ文件做成静态链接库,我想看看这种方式如何链接的,我使用gcc -c main.o -o main.o, gcc main.o -L"./“ -o main(liband.a在当前目录),但是不成功,报错如下:
main.o: In function `main':
main.c.text+0x42): undefined reference to `and'
collect2: ld 返回 1
但是使用gcc main.o liband.a -o main,可以编译出程序,所以我比较奇怪,为什么指定lib文件夹不成功。
3.对于#include <stdio.h>这种系统库,我没有在export的环境变量中看到,所以我想请问如何找到的对应的库和头文件。
希望大家帮帮忙,谢谢。

论坛徽章:
0
2 [报告]
发表于 2010-07-27 12:51 |只看该作者
上传代码时记得使用code标签。

论坛徽章:
0
3 [报告]
发表于 2010-07-27 13:31 |只看该作者
1、因为C语言里,未声明就默认为int返回值类型的函数。如果你把函数改一下:
double and(int a, int b),应该就不能编译了。
2、3、没试过不知道。

论坛徽章:
0
4 [报告]
发表于 2010-07-27 13:38 |只看该作者
本帖最后由 churchmice 于 2010-07-27 13:50 编辑

2.你都没告诉gcc去链接什么库,gcc有这么牛逼能猜到你要去链接liband.a么?

kernel@fairland:~/tmp$ cc main.o -land -o main
/usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../../i686-pc-linux-gnu/bin/ld: cannot find -land
collect2: ld returned 1 exit status
kernel@fairland:~/tmp$ cc main.o -L. -land -o main

3.看你的gcc spec,一般默认会搜寻/usr/include等文件夹
你也可以通过设置$C_INCLUDE_PATH和$CPLUS_INCLUDE_PATH自己添加
可以通过如下命令查看

  1. cpp -v </dev/null
复制代码
#include "..." search starts here:
#include <...> search starts here:
/home/kernel/lib
/usr/local/include
/usr/lib/gcc/i686-pc-linux-gnu/4.4.4/include
/usr/lib/gcc/i686-pc-linux-gnu/4.4.4/include-fixed
/usr/include
End of search list.

第一个是我自己在$C_INCLUDE_PATH里面添加的
[quote]

论坛徽章:
0
5 [报告]
发表于 2010-07-27 13:46 |只看该作者
1. 不清楚。
2. 需要指定库的名字。
3. 在系统目录下,你可以搜搜。。。

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
6 [报告]
发表于 2010-07-27 16:49 |只看该作者
1.使用函数之前不显示声明,便隐式将其返回值声明为int。参数个数MS声明为变长,即便后面又接着写了函数的定义:
  1. int main (){
  2.   add (3);
  3.   add (3,4,4,5);
  4.   return 0;
  5. }

  6. int add (int a,int b){
  7. }
复制代码
[yan@localhost ~]$ gcc declare.c

没有报错。。。。。。

2.不清楚。
2.你都没告诉gcc去链接什么库,gcc有这么牛逼能猜到你要去链接liband.a么?
churchmice 发表于 2010-07-27 13:38

我们平时编译的时候也没指明库。对于printf等标准函数,gcc会自动在相应的库里去找代码吗?
gcc  -L. -L/home/fred/lib prog.o
这是在《GCC Complete Reference》里的例子,书中说这句话告诉linker如果在默认目录下没找到所要的库时就去当前目录和/home/fred/lib里去找。
但是命令行里并没有指定去找哪个库呀!给定了搜索目录,但还是不知道所需代码在哪个库文件里,如果不去遍历所有库文件,那个-L有什么意义呢?

3.头文件MS在编译GCC时硬写进去的,在编译时加--verbos可以看到GCC是从哪里找头文件。
想更改路径,要么加-I,要么设置环境变量,要么重新编译GCC。

论坛徽章:
0
7 [报告]
发表于 2010-07-27 17:54 |只看该作者
回复 6# tempname2

stdio种的函数在libc里面,gcc会自动链接 (-lc )

尽信书不如无书

-L用来添加link的路径,对应的有$LIBRARY_PATH,我那个例子已经很清楚了

假如真如你所说gcc把所有的库都给你找一遍那问题就大了,如果一个函数在多个库里面都有定义,那gcc用哪个?这样出的莫名其妙的问题不要太多

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
8 [报告]
发表于 2010-07-27 18:21 |只看该作者
回复  tempname2

stdio种的函数在libc里面,gcc会自动链接 (-lc )

尽信书不如无书

-L用来添加li ...
churchmice 发表于 2010-07-27 17:54


我都说了这个问题我不是很清楚。我只是问问,没有质疑你发言的意思,为什么你好像很气愤的样子。。。。。。。

-L用来添加link的路径,对应的有$LIBRARY_PATH,我那个例子已经很清楚了


以前大致浏览了一下《GCC Complete Reference》,印象中,链接的时候,linker会查找相应目录的所有库文件,所以看到LZ说的问题觉得有点奇怪。

后来又看到你的发言,觉得和我印象中的完全矛盾了。专门跑到Linux下试了下,还真的不会自动查找。

于是又翻了翻《GCC Complete Reference》,于是看到了我提到的那句命令,心里有疑,就问了。

-L和LIBRARY_PATH的作用我知道,我只是想问问,没有指定库文件linker会不会去搜索,不然-L单独用就没有意义了。

或者-L本身就不单独用?我代码写的少,平时也不注意看make的输出,还真没留意。。。。。。。

假如真如你所说gcc把所有的库都给你找一遍那问题就大了,如果一个函数在多个库里面都有定义,那gcc用哪个?这样出的莫名其妙的问题不要太多


这个问题我在哪看到过,先逮着哪个用哪个。

突然又记起来,默认情况下,标准库是动态链接来着(很不确定的语气)。。。。。。

论坛徽章:
0
9 [报告]
发表于 2010-07-27 19:06 |只看该作者
回复 8# tempname2

额,sorry,无意冒犯,我说话是冲了点(这两天火气比较大)

论坛徽章:
0
10 [报告]
发表于 2010-07-27 19:08 |只看该作者
回复 8# tempname2

re,搜寻顺序是根据命令行给出的顺序来链接的
-lfirst -lsecond -lthird
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP