C语言:源文件 头文件【.c/.cc/.h】的使用

函数声明与定义分离的重要性及条件编译避免重复定义

一个函数包括定义与声明,定义中包含了函数是如何实现的,声明则阐明函数如何被调用。
工程上为了将个函数模块化,通常将声明与定义分开,一般将主函数定义放在.c中,其他函数定义放在源文件.cc中,函数声明放在.h中。
.c 中包含主函数,并include所有使用到的头文件;
.cc中包含其他函数定义,并include需要的.h文件或需要的非本函数的声明;【保证这个源文件可以单独编译成功
如果不将函数的声明与定义分开,将函数声明和定义都放在.h中,那如果现在要增加一个函数的声明文件2.c,这个新函数include其他头文件1.h,那么在编译1.c和2.c时,1.h中的函数定义将在对象文件中出现两次,报duplicated错误。
简而言之,如果不分开,其他.c文件可能只是想用一下前面函数的声明,但确错误地一并引入函数定义,就会报错。
.h中包含库函数声明,一些函数的声明。

还有一个问题,万一.h中有函数定义,这时,如果重复包含头文件,同样会报duplicated错误,因为.h在预编译时进行简单替换,就会出现多个同样的函数定义。
解决方法为条件编译:

#ifndef _HEADERS1_H//未定义,执行如下操作,如有定义,则不执行
#define _HEADERS1_H//定义宏
..<
uilibTrafficTest.c:130:5: error: conflicting types for 'trafficTestPacketSet' int trafficTestPacketSet(char *portListStr, char *rawPacket, UINT8 packetIndex, ^ In file included from uilibTrafficTest.c:30:0: ../../../../../../src/application/include/uilib/uilibTrafficTest.h:45:5: note: previous declaration of 'trafficTestPacketSet' was here int trafficTestPacketSet(char *portListStr, char *rawPacket, UINT8 packetIndex, ^ In file included from ../../../../../../src/platform/include/userPort/up_spec.h:11:0, from ../../../../../../src/platform/include/userPort/user_port_pvt.h:89, from ../../../../../../src/platform/include/userPort/user_port.h:88, from uilibTrafficTest.c:15: uilibTrafficTest.c: In function 'trafficTestPacketSet': uilibTrafficTest.c:154:118: error: pointer targets in passing argument 4 of 'tpConfig_objAddFieldStrForSet' differ in signedness [-Werror=pointer-sign] PFM_IF_FAIL_DONE_RET(ret, tpConfig_objAddFieldStrForSet(&stInput, TPCONFIG_INIT_ENTRY, CFG_TRAFFIC_TEST_F_SRC_MAC, srcMac), ERR_BAD_PARAM); ^ ../../../../../../src/platform/include/fepPfm.h:151:14: note: in definition of macro 'PFM_IF_FAIL_DONE_RET' int _rv = (expression);\ ^ In file included from uilibTrafficTest.c:14:0: ../../../../../../src/platform/include/midware/tpConfig.h:1084:5: note: expected 'const char *' but argument is of type 'INT8 * {aka signed char *}' int tpConfig_objAddFieldStrForSet(TPCONFIG_SET_INPUT *pInput, int type, const char *pField, const char *pStr); ^ In file included from ../../../../../../src/platform/include/userPort/up_spec.h:11:0, from ../../../../../../src/platform/include/userPort/user_port_pvt.h:89, from ../../../../../../src/platform/include/userPort/user_port.h:88, from uilibTrafficTest.c:15: uilibTrafficTest.c:155:118: error: pointer targets in passing argument 4 of 'tpConfig_objAddFieldStrForSet' differ in signedness [-Werror=pointer-sign] PFM_IF_FAIL_DONE_RET(ret, tpConfig_objAddFieldStrForSet(&stInput, TPCONFIG_INIT_ENTRY, CFG_TRAFFIC_TEST_F_DST_MAC, dstMac), ERR_BAD_PARAM); ^ ../../../../../../src/platform/include/fepPfm.h:151:14: note: in definition of macro 'PFM_IF_FAIL_DONE_RET' int _rv = (expression);\ ^ In file included from uilibTrafficTest.c:14:0: ../../../../../../src/platform/include/midware/tpConfig.h:1084:5: note: expected 'const char *' but argument is of type 'INT8 * {aka signed char *}' int tpConfig_objAddFieldStrForSet(TPCONFIG_SET_INPUT *pInput, int type, const char *pField, const char *pStr); ^ In file included from ../../../../../../src/platform/include/userPort/up_spec.h:11:0, from ../../../../../../src/platform/include/userPort/user_port_pvt.h:89, from ../../../../../../src/platform/include/userPort/user_port.h:88, from uilibTrafficTest.c:15: uilibTrafficTest.c:156:117: error: passing argument 4 of 'tpConfig_objAddFieldStrForSet' from incompatible pointer type [-Werror=incompatible-pointer-types] PFM_IF_FAIL_DONE_RET(ret, tpConfig_objAddFieldStrForSet(&stInput, TPCONFIG_INIT_ENTRY, CFG_TRAFFIC_TEST_F_SRC_IP, srcIp), ERR_BAD_PARAM); ^ ../../../../../../src/platform/include/fepPfm.h:151:14: note: in definition of macro 'PFM_IF_FAIL_DONE_RET' int _rv = (expression);\ ^ In file included from uilibTrafficTest.c:14:0: ../../../../../../src/platform/include/midware/tpConfig.h:1084:5: note: expected 'const char *' but argument is of type 'INT16 * {aka short int *}' int tpConfig_objAddFieldStrForSet(TPCONFIG_SET_INPUT *pInput, int type, const char *pField, const char *pStr); ^ In file included from ../../../../../../src/platform/include/userPort/up_spec.h:11:0, from ../../../../../../src/platform/include/userPort/user_port_pvt.h:89, from ../../../../../../src/platform/include/userPort/user_port.h:88, from uilibTrafficTest.c:15: uilibTrafficTest.c:157:117: error: passing argument 4 of 'tpConfig_objAddFieldStrForSet' from incompatible pointer type [-Werror=incompatible-pointer-types] PFM_IF_FAIL_DONE_RET(ret, tpConfig_objAddFieldStrForSet(&stInput, TPCONFIG_INIT_ENTRY, CFG_TRAFFIC_TEST_F_DST_IP, dstIp), ERR_BAD_PARAM); ^ ../../../../../../src/platform/include/fepPfm.h:151:14: note: in definition of macro 'PFM_IF_FAIL_DONE_RET' int _rv = (expression);\ ^ In file included from uilibTrafficTest.c:14:0: ../../../../../../src/platform/include/midware/tpConfig.h:1084:5: note: expected 'const char *' but argument is of type 'INT16 * {aka short int *}' int tpConfig_objAddFieldStrForSet(TPCONFIG_SET_INPUT *pInput, int type, const char *pField, const char *pStr); ^ cc1: all warnings being treated as errors CMakeFiles/uilib.dir/build.make:1313: recipe for target 'CMakeFiles/uilib.dir/uilibTrafficTest.c.o' failed make[4]: *** [CMakeFiles/uilib.dir/uilibTrafficTest.c.o] Error 1 CMakeFiles/Makefile2:107: recipe for target 'CMakeFiles/uilib.dir/all' failed make[3]: *** [CMakeFiles/uilib.dir/all] Error 2 Makefile:132: recipe for target 'all' failed make[2]: *** [all] Error 2 package/tplink/tplink-generic.mk:289: recipe for target '/project/fep_source_2/buildroot/build/ac5x_pro/build/tplink/uilib-1.0/.stamp_built' failed make[1]: *** [/project/fep_source_2/buildroot/build/ac5x_pro/build/tplink/uilib-1.0/.stamp_built] Error 2 Makefile:84: recipe for target '_all' failed make: *** [_all] Error 2 解释下报错
10-28
cli_common.c:12228:37: error: passing argument 3 of 'pthread_create' from incompatible pointer type [-Werror=incompatible-pointer-types] if(0 != (pthread_create(&t_id,NULL,fwcli_stdinToMaster,(void *)&slave_sock))) ^ In file included from ../../../../../../../src/platform/include/h/wrn/wm/common/wmos.h:187:0, from ../../../../../../../src/platform/include/h/wrn/wm/common/wm.h:70, from cli_common.c:34: ../../../../host/aarch64-buildroot-linux-gnu/sysroot/usr/include/pthread.h:233:12: note: expected 'void * (*)(void *)' but argument is of type 'void (*)(void *)' extern int pthread_create (pthread_t *__restrict __newthread, ^ cli_common.c:12232:3: error: implicit declaration of function 'fwcli__stopUseFakeConsole' [-Werror=implicit-function-declaration] fwcli__stopUseFakeConsole(); ^ cli_common.c: At top level: cli_common.c:12255:7: error: conflicting types for 'fwcli_stdinToMaster' void *fwcli_stdinToMaster(void * arg) ^ In file included from ../../../../../../../src/platform/include/h/wrn/wm/cli/rcc.h:61:0, from cli_common.c:36: ../../../../../../../src/platform/include/h/wrn/wm/cli/cli_common.h:973:13: note: previous declaration of 'fwcli_stdinToMaster' was here static void fwcli_stdinToMaster(void * arg); ^ cli_common.c:12331:6: error: conflicting types for 'fwcli__stopUseFakeConsole' [-Werror] void fwcli__stopUseFakeConsole() ^ cli_common.c:12232:3: note: previous implicit declaration of 'fwcli__stopUseFakeConsole' was here fwcli__stopUseFakeConsole(); ^ In file included from ../../../../../../../src/platform/include/h/wrn/wm/cli/rcc.h:61:0, from cli_common.c:36: ../../../../../../../src/platform/include/h/wrn/wm/cli/cli_common.h:973:13: error: 'fwcli_stdinToMaster' used but never defined [-Werror] static void fwcli_stdinToMaster(void * arg); ^ cc1: all warnings being treated as errors src/CMakeFiles/cliDev.dir/build.make:1469: recipe for target 'src/CMakeFiles/cliDev.dir/cli_common.c.o' failed make[4]: *** [src/CMakeFiles/cliDev.dir/cli_common.c.o] Error 1 CMakeFiles/Makefile2:154: recipe for target 'src/CMakeFiles/cliDev.dir/all' failed make[3]: *** [src/CMakeFiles/cliDev.dir/all] Error 2 Makefile:132: recipe for target 'all' failed make[2]: *** [all] Error 2 package/tplink/tplink-generic.mk:289: recipe for target '/project/code_source_repository/fep_source/buildroot/build/armv8/build/tplink/cli-1.0/.stamp_built' failed make[1]: *** [/project/code_source_repository/fep_source/buildroot/build/armv8/build/tplink/cli-1.0/.stamp_built] Error 2 Makefile:84: recipe for target '_all' failed
09-30
PS C:\Users\34171\Desktop\code\WJ> g++ main.c recipe_manager.c utils.c -o wj D:/TDM-GCC/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\34171\AppData\Local\Temp\ccWNei0S.o:main.c:(.text+0xc0): undefined reference to `add_recipe()' D:/TDM-GCC/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\34171\AppData\Local\Temp\ccWNei0S.o:main.c:(.text+0xc7): undefined reference to `delete_recipe()' D:/TDM-GCC/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\34171\AppData\Local\Temp\ccWNei0S.o:main.c:(.text+0xce): undefined reference to `modify_recipe()' D:/TDM-GCC/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\34171\AppData\Local\Temp\ccWNei0S.o:main.c:(.text+0xd5): undefined reference to `search_recipes()' D:/TDM-GCC/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\34171\AppData\Local\Temp\ccWNei0S.o:main.c:(.text+0xdc): undefined reference to `random_recommendation()' D:/TDM-GCC/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\34171\AppData\Local\Temp\ccWNei0S.o:main.c:(.text+0xe3): undefined reference to `manage_likers()' D:/TDM-GCC/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\34171\AppData\Local\Temp\cc4Vzb53.o:utils.c:(.rdata$.refptr.recipes[.refptr.recipes]+0x0): undefined reference to `recipes' D:/TDM-GCC/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\34171\AppData\Local\Temp\cc4Vzb53.o:utils.c:(.rdata$.refptr.recipe_count[.refptr.recipe_count]+0x0): undefined reference to `recipe_count' collect2.exe: error: ld returned 1 exit status PS C:\Users\34171\Desktop\code\WJ>
07-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值