+ -
当前位置:首页 → 问答吧 → 头文件和源文件的问题

头文件和源文件的问题

时间:2010-07-27

来源:互联网

大家好:
          我遇到一个问题突然不太清晰,就是说头文件和源文件的问题。
          为了搞清楚之间的关系,我写了三个文件,分别为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的环境变量中看到,所以我想请问如何找到的对应的库和头文件。
希望大家帮帮忙,谢谢。

作者: caowangyang   发布时间: 2010-07-27

上传代码时记得使用code标签。

作者: davelv   发布时间: 2010-07-27

1、因为C语言里,未声明就默认为int返回值类型的函数。如果你把函数改一下:
double and(int a, int b),应该就不能编译了。
2、3、没试过不知道。

作者: julynada   发布时间: 2010-07-27

本帖最后由 churchmice 于 2010-07-27 13:50 编辑

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



QUOTE:
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
复制代码


QUOTE:
#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]

作者: churchmice   发布时间: 2010-07-27

1. 不清楚。
2. 需要指定库的名字。
3. 在系统目录下,你可以搜搜。。。

作者: rain_fish   发布时间: 2010-07-27

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. }
复制代码


QUOTE:
[yan@localhost ~]$ gcc declare.c


没有报错。。。。。。

2.不清楚。


QUOTE:
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。

作者: tempname2   发布时间: 2010-07-27