免费注册 查看新帖 |

Chinaunix

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

[C] C头文件中函数声明问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-15 09:50 |只看该作者 |倒序浏览
//head.h
void donothing(){}



//head.h
void donothing();
//head.c
void donothing(){}

除了可读性,有无区别?

论坛徽章:
0
2 [报告]
发表于 2009-04-15 09:58 |只看该作者

回复 #2 j1111011 的帖子

我同意
多谢解答

论坛徽章:
0
3 [报告]
发表于 2009-04-15 10:14 |只看该作者
我觉得还是分开的好,这样头文件引用不容易出错

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2009-04-15 10:22 |只看该作者
原帖由 daxi1987 于 2009-4-15 09:50 发表
//head.h
void donothing(){}

这是定义。

//head.h
void donothing();

这才是声明。
除了可读性,有无区别?

当然有了,第一种写法很容易出现多次定义的问题。

论坛徽章:
0
5 [报告]
发表于 2009-04-15 10:53 |只看该作者

回复 #5 MMMIX 的帖子

的确可能出现多次定义(出现两次#include"head.h"),还是按原则分开为.h .c的好
.hpp不会出现多重定义,这是和.h的区别

论坛徽章:
0
6 [报告]
发表于 2009-04-15 11:43 |只看该作者

回复 #1 daxi1987 的帖子

按我的理解, 在.h中定义(不是声明)函数, 相当于在include这个.h的所有.c中分别定义这个函数. 这些.c文件编译生成.o后, 每个.o都有这个函数的实现.
然后这些.o链接在一起呢? 我不知道这些实现会不会合并.

论坛徽章:
0
7 [报告]
发表于 2009-04-15 12:15 |只看该作者

回复 #9 j1111011 的帖子

是了. 看来这些定义了相同函数的.o在链接在一起的时候会被编译器认为重定义.

论坛徽章:
0
8 [报告]
发表于 2009-04-15 12:21 |只看该作者
原帖由 j1111011 于 2009-4-14 19:13 发表
出现两次 #include"head.h" 这个就报错,分开你的.h .c也是一样会报错,问题不是在分不分开,而是你的头文件写的有问题,。,。
#ifndef
#define
#endif
t.h
#ifndef _X_
#define _X_
void empty(){
}
...


没用的,你再试试另一个whatever.c也#include "t.h",然后连接起来,看看有没有多重定义?

论坛徽章:
0
9 [报告]
发表于 2009-04-15 13:01 |只看该作者
“包含”只是简单的包含,把 <> 或者 "" 里面的文件内容原封不动地挪进来。
至于重复定义、#if 命令之类的,那都是你把包含考虑进去之后应该注意的事情。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
10 [报告]
发表于 2009-04-15 15:31 |只看该作者
原帖由 daxi1987 于 2009-4-15 10:53 发表
的确可能出现多次定义(出现两次#include"head.h"),还是按原则分开为.h .c的好
.hpp不会出现多重定义,这是和.h的区别


.hpp 和 .h 没有本质区别, 同C++标准库中不带后缀名的头文件一样, 都是一个文本文件而已。
(当然, 标准库头文件通常是有真实物理文件对应, 但也不必如此)


//head.h
void donothing(){}

此种写法, 无论文件采用什么后缀名, 都是错误的。
因为它违反了一个约定:  头文件不允许定义具有外部链接的实体, inline和模板除外

这种写法,通常会在链接时出现重定义符号错误。
除非包含该头文件的C翻译单元的数目少于等于1并且包含该头文件的C++翻译单元的数目少于等于1。


如果一定要将一个函数(非函数模板)的实现——函数体——写在头文件中, 有如下方法:
1. 使用inline。  是上述约定中的例外情况。
2. 使用 static 或者无名名字空间, 使得函数不再具有外部链接属性。


函数模板和类模板的定义——实现体, 目前绝大多数编译器都要求其出现在头文件中。
所以boost的头文件中才具有实现体。

因为boost的头文件只能供C++程序使用, 为了与普通的.h区分, 所以另用了一个 .hpp来表示。
但是要注意, 能在头文件中放实现体的真正原因是因为它们是模板, 而不是因为文件后缀名是.hpp。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP