注册 登录
编程论坛 Linux教室

试着在Linux上编程,有个问题十分不解...

神龙赖了 发布于 2013-01-06 21:47, 2379 次点击
在Linux中书上一般是由几个c文件链接起来一起生成:
程序代码:
/* myfile.c */
#include <stdio.h>
#include "getname.h"

int main(void)
{
  printf("\r\nplease enter your name:\r\n");
  getname();
  return 0;
}
程序代码:
/* getname.c */
#include <stdio.h>
#include "getname.h"

void getname(void)
{
  char name[28];
  scanf("%s",name);
  printf("\r\nHello %s!\r\n\r\n\r\n",name);
}
程序代码:
/* getname.h */
#ifdef GETNAME_H
#undef GETNAME_H
printf("Error!\r\n");
void getname(void);
#endif
用gcc myfile.c /root/New/getname.c -o myfile.exe -INew生成可运行程序myfile.exe
我链接后运行发现并没有出现错误,可是getname.h头文件中的print("")语句没有输出
那getname.h岂不是没有作用了?
21 回复
#2
神龙赖了2013-01-06 22:08
还有,如果getname.h改成
#ifndef GETNAME_H
#define GETNAME_H
printf("Error!\r\n");
void getname(void);
#endif

这样好像就错误了,gcc说是printf非法,可是应该不会啊?
当然,主要是上面一个问题
#3
wp2319572013-01-06 23:22
1、printf非法是因为没有包含头文件吧

2、头文件貌似只编译需要的部分  并不是把整个头文件都编译到exe中

以上2点均是貌似  基础不牢  呵呵

#4
神龙赖了2013-01-07 00:19
对哦,不能用printf,以前在windos上直接写上了#include <stdio.h>
结果一直没去管它了...
2、头文件貌似只编译需要的部分  并不是把整个头文件都编译到exe中

这里有点疑问,因为如果getname.h头文件中
#ifdef GETNAME_H
#undef GETNAME_H
printf("Error!\r\n");
void getname(void);
#endif

不执行的话getname函数就没有初始化定义了,程序应该会出错的啊?
还有头文件的制作是避免重复的定义,那为什么不在main函数中直接定义呢?这样的话既可以不重复定义而且也比较省力
函数和main函数()中的头文件都会重复,合并时不会出错吗?主要是不懂合并的流程...
Linux刚用,太菜了,求教...
#5
zklhp2013-01-07 11:44
这和linux有啥关系咧
#6
神龙赖了2013-01-07 11:52
因为我是在Linux上写的代码啊...如果是在Windos上写就直接是一个c文件了
话说windos上也能合成的吗?小弟才疏学浅,望指教上面的问题啊,当然这个最好能顺便说明一下...
z版得帮帮忙啊,可不能老是切分啊,会折寿滴...
#7
zklhp2013-01-07 12:14
以下是引用神龙赖了在2013-1-7 11:52:03的发言:

因为我是在Linux上写的代码啊...如果是在Windos上写就直接是一个c文件了
话说windos上也能合成的吗?小弟才疏学浅,望指教上面的问题啊,当然这个最好能顺便说明一下...
z版得帮帮忙啊,可不能老是切分啊,会折寿滴...

除了是在linux下做的这个实验 我没看出和linux有啥其他的关系 用微软的编译器也可以这么弄 只不过具体的参数不同罢了

还有头文件的制作是避免重复的定义,那为什么不在main函数中直接定义呢?这样的话既可以不重复定义而且也比较省力


为啥呢 如果有很多头文件 不就乱了 所以要有头文件 所以要防止头文件重复引用

不过你这里的头文件防重复引用弄的是不是不对啊。。。

看看stdio.h里面怎么实现的

程序代码:

#ifndef _STDINT_H
#define _STDINT_H
……这里是省略的意思……
#endif


一般不在头文件里面写printf("……");这样的东西罢
#8
神龙赖了2013-01-07 12:21
额,我知道不对了,3楼已经说了是printf函数没有定义,
但是程序没有出错,说明根本没有到void getname(void);
那getname函数岂不是没有定义了吗?那不是会出错吗?
还有像<stdio.h>这样的头文件不是一样重复了吗?它们怎么不算重复定义呢?
我彻底混淆了...z版还请继续讲。。。
#9
zklhp2013-01-07 12:22
以下是引用zklhp在2013-1-7 12:14:08的发言:


除了是在linux下做的这个实验 我没看出和linux有啥其他的关系 用微软的编译器也可以这么弄 只不过具体的参数不同罢了



为啥呢 如果有很多头文件 不就乱了 所以要有头文件 所以要防止头文件重复引用

不过你这里的头文件防重复引用弄的是不是不对啊。。。

看看stdio.h里面怎么实现的


#ifndef _STDINT_H
#define _STDINT_H
……这里是省略的意思……
#endif


一般不在头文件里面写printf("……");这样的东西罢
不过好像你这里不是想实现防重复引用 而是在没有这样编译的时候防止出错? 不知道你咋琢磨出的这个东西。。。
#10
zklhp2013-01-07 12:24
以下是引用神龙赖了在2013-1-7 12:21:34的发言:

额,我知道不对了,3楼已经说了是printf函数没有定义,
但是程序没有出错,说明根本没有到void getname(void);
那getname函数岂不是没有定义了吗?那不是会出错吗?
还有像这样的头文件不是一样重复了吗?它们怎么不算重复定义呢?
我彻底混淆了...z版还请继续讲。。。

为啥stdio.h不会重复定义就是因为用了上面的那种宏 你混淆了我也糊涂了 不知道你到底想知道什么 不知道你想干什么。。。
#11
神龙赖了2013-01-07 12:27
哦,哟西哟西,
但是getname函数在main函数中没有定义啊,那不是会出错?
#12
zklhp2013-01-07 12:27
程序代码:

/* getname.h */
#ifdef GETNAME_H
#undef GETNAME_H
printf("Error!\r\n");
void getname(void);
#endif


你这里的逻辑是 如果定义了 就取消定义 而你这个程序里面没有定义 所以 不会有效

如果你改成ifndef 没定义才执行 那就出错

关键还是看你想干什么 不知道你这代码打哪看的。。
#13
zklhp2013-01-07 12:29
以下是引用神龙赖了在2013-1-7 12:27:09的发言:

哦,哟西哟西,
但是getname函数在main函数中没有定义啊,那不是会出错?

1 在main()里面写其他函数的定义是错误的 至少是不规范的 函数是独立的 只有调用的关系 没有包含的关系 这是C的基础

2 为啥不会出错 你看看你的编译参数咋写的。。
#14
zklhp2013-01-07 12:30
/root/New/getname.c

还有 嗯 你直接用root了 很厉害嘛

据说这样不安全 不过我一直这么用得。。。
#15
神龙赖了2013-01-07 12:30
自己稀里糊涂撞出来的...
我的意思是printf下面一句
void getname(void);
这一句是定义getname函数用的,如果没有执行它的话就相当于没有初始化getname函数啊?
貌似是吧...
#16
神龙赖了2013-01-07 12:32
哦,这样啊。。。
可是...可是什么去了啊...
#17
神龙赖了2013-01-07 12:34
哦对了,可是getname.h头文件也执行不到它定义的地方啊,那不就根本没有它的定义了?
看来我是问上瘾了...
#18
zklhp2013-01-07 12:38
以下是引用神龙赖了在2013-1-7 12:30:33的发言:

自己稀里糊涂撞出来的...
我的意思是printf下面一句
void getname(void);
这一句是定义getname函数用的,如果没有执行它的话就相当于没有初始化getname函数啊?
貌似是吧...

严格来说是声明罢 定义和声明的区别谭浩强书里都有

比如你这里 如果要防重复引用可以这样

程序代码:

/* getname.h */
#ifndef GETNAME_H
#define GETNAME_H
void getname(void);
#else
#warning 出错了哦 貌似重复引用了诶 快给zklhp分
#endif


程序代码:

/* myfile.c */
#include <stdio.h>
#include "getname.h"
#include "getname.h"

int main(void)
{
    printf("\r\nplease enter your name:\r\n");
    getname();
    return 0;
}



故意重复引用 看会怎么样呢

gcc -Wall myfile.c getname.c -o myfile.exe
In file included from myfile.c:4:0:
getname.h:6:2: warning: #warning 出错了哦 貌似重复引用了诶 快给zklhp分 [-Wcpp]

还有啊 linux里不需要用.exe 作为后缀。。
#19
神龙赖了2013-01-07 12:49
额,又学到一点,只可惜不是我要的那一点...
好吧,就说得干脆一点
#include "getname.h"
把所有文件中的这一行代码去掉,文件照常可以正常运行,这是为啥捏?
看你这么猴急就先给了分吧,先说好啊,给了可不许跑啊...
#20
神龙赖了2013-01-07 12:54
我擦,不会跑了吧?这神马情况?
别啊,说明白点c版上还有20分啊...
#21
zklhp2013-01-07 12:54
以下是引用神龙赖了在2013-1-7 12:49:53的发言:

额,又学到一点,只可惜不是我要的那一点...
好吧,就说得干脆一点
#include "getname.h"
把所有文件中的这一行代码去掉,文件照常可以正常运行,这是为啥捏?
看你这么猴急就先给了分吧,先说好啊,给了可不许跑啊...

因为你编译的时候编译参数里面分别写了两个C文件罢 应该就相当于 两个.c文件分别编译为.o文件 再链接到一块

那样 对于程序来说应该是没问题的啊 相当于会跑到其他地方找这个函数罢

工头喊我搬砖去了 有问题可以去C语言版问大牛们了 这个问题其实和linux没特别大关系的

祝楼主学习顺利
#22
神龙赖了2013-01-07 13:06
在c版又问了下,已经全部弄懂了
非常感谢你能抗住我这么强大的问题攻击...
1