|
今天分享的是一个比较生僻的C语言知识点,大家平时都用过#include"xxx.h"应该很少或者几乎没有见过.c文件作为头文件吧,那么今天bug菌就跟大家一起来学习一下。 % F# ?) \. Y7 x 1、操作一波 咱们先体验一波#include"xxx.c"文件能不能用: + i6 v" ~' ]$ N4 b3 s' R) y 7 p7 l+ S" _! ^2 ?' ]; d01 体验一下 参考demo:1//FileName :main 2#include <stdio.h> 3#include <stdlib.h>0 N3 g7 f/ ?8 \' f& Q8 { 47 z- l$ }) ] ?4 L# _9 N% V9 T 5/*************************** 6 * .c文件声明区域 7 **************************/ 8#include"module1.c" 9#include"module2.c" 10# V; E7 ?/ \5 q+ ~+ C 11/***************************9 W- _7 r/ v: v2 c: P# z 12 * Fuction: main 13 * Author 公众号:最后一个bug) , }& o5 `! T! j9 ?9 g14 **************************/ 15int main(int argc, char *argv[]) { 16 17 Fuction1(); : v/ F1 Q2 y. o4 A 18 Fuction2(); 19 printf("欢迎关注公众号:最后一个bug\n"); 20 return 0; 21} # ^- A: L. Y- N! k 1//FileName: Module1.c 3 I, W6 [% V+ b7 ]) M6 P2#include<stdio.h>$ ~. x$ G) C v 3/*************************** 4 * Fuction: Fuction1. y0 Y! {, Y# B8 x 5 * Author 公众号:最后一个bug) 0 V7 q6 W! M* \+ M4 K6 **************************/3 @! V: X. ^$ F 7void Fuction1()9 h! W; ?* c# E; y7 N) { 8{ 9 printf("Run Fuction1\n"); c6 X8 V& M: @# Z 10} 6 c. V* B5 W8 J/ }7 t' I8 Q4 Y 1//FileName: Module2.c ) N# L: _. V( n8 R2#include<stdio.h> 3/*************************** 4 * Fuction: Fuction25 N7 r9 {) U- ~( r- Z- o 5 * Author 公众号:最后一个bug) 6 **************************/ 7void Fuction2() 8{ 9 printf("Run Fuction2\n");$ W' K6 E2 l- F 10} 输出结果:
分析一下: 看来这波操作可行,似乎还省去了.h文件,之前bug菌说过,分析.h文件的时候直接把.h文件在对应的.c文件中的位置处展开然后进一步分析即可,其实这.c文件也是如此,接着往下看。 / `8 _, ?, E, |( s2 d+ W 2 n% l0 Y( f4 Y5 I6 p- S) x02 加深理解 " j7 i/ ]$ T3 a6 ^9 | 参考demo:1//FileName :main 2#include <stdio.h>& b# p& _7 A. d, v 3#include <stdlib.h> 4! H8 K' X e: {8 ~ 5char * cBug1 = "bugNo1"; //这里是位置1 6char * cBug2 = "bugNo2";2 Q* d. R0 I" @0 c8 k3 y- a. H/ b 7/***************************% l9 j y3 f6 F 8 * .c文件声明区域 + { o- p K3 e! l7 u9 V 9 **************************/& h9 _6 i% j# X. u1 D* e9 z* r3 I4 @ 10#include"module1.c" 11#include"module2.c"; `% Q: o: i9 [1 v( C9 w2 W( @ 12 13//char * cBug1 = "bugNo1";//这里是位置2 14//char * cBug2 = "bugNo2"; 153 L- \, p& ] U/ ] 16/*************************** 17 * Fuction: main- \, R# k6 D( f 18 * Author 公众号:最后一个bug) / W" M4 C' ~" Q$ H: ^19 **************************/ 20int main(int argc, char *argv[]) {( m3 g' L" o9 \& H; n; N* c 21 22 Fuction1(); , X f% d8 p& c9 g( l& e 23 Fuction2(); 24 printf("欢迎关注公众号:最后一个bug\n"); 25 return 0; 26}0 v( {( M& O9 r , Z6 o( U9 _1 r0 @1 l 1//FileName: Module2.c . d: {: O7 ~+ }. o2#include<stdio.h> 3/*************************** 4 * Fuction: Fuction1 5 * Author 公众号:最后一个bug) 4 l! p+ K" z' Z- j% \, B6 **************************/6 d0 q5 _/ ~4 O' o, s9 y0 X1 b$ b l; }/ J 7void Fuction1() 8{ 9 printf("Run Fuction1\n");4 `& u4 f, z# e; J4 J 10 printf("%s\n",cBug1); 11} 8 T& h+ ]& ^( y$ X% G2 W 1//FileName: Module2.c ' R; {0 V( I8 j* L' l' Q# F2#include<stdio.h>( S. A1 @7 |. ~$ Z 3/*************************** 4 * Fuction: Fuction2 5 * Author 公众号:最后一个bug) 6 **************************/9 U+ n) J6 ?% \' Q& Y- L 7void Fuction2()9 c7 B8 y3 P$ } 8{4 x) D9 T: [5 h- Y6 D- I9 f 9 printf("Run Fuction2\n"); 10 printf("%s\n",cBug2);0 p* M4 P2 ]( \% a/ J* ]* b4 I4 A 11} 输出结果:
分析一下: 我们在位置1进行两个变量的定义,成功编译运行得到如上的结果,符合我们的预期,然而当我们去掉位置1进行位置2的定义,程序却无法进行编译,看来跟我们预期在编译过程中直接展开.c文件是一致的。 / V) S' P9 d6 V) K 3、有什么用? 这种方式在bug菌的编码历史长河中一般只在两种情况下用到: 9 V8 F, B2 L x& z3 n8 O' F3 |: h* h 1、维护毫无设计的代码. e% [' z2 O$ o+ i4 |# u+ H M" p: Q# [4 z7 o 有些历史悠久的项目经过了N多位大佬的蹂躏,说实在的代码结构上已经非常可怕了,往往每个源文件内容非常之长,为了保持代码原样,会采用#include"xxx.c"把这几的相关文件嵌入进去,也便于自己后期维护。 + F3 P% H3 x4 J; ^4 ]3 V: ] 2、测试代码 0 s% Q( N/ F( r5 x; Q6 ^8 P" m- Q! u7 R x4 X( z7 d7 R' j 在前期进行软件调试的时候可能自己会在不同的文件中安插不同测试功能函数,通过这样方法可以方便的引入和剔除。 , B& `( E& J# I. T 比如说你需要对源文件中的一些静态变量进行相关的监控处理,然而又不想在本文件中增加测试代码,于是便可以在#include"xxx.c"中进行测试函数的编写来供使用,比如 : 2#include <stdio.h>3 t4 G4 D/ K) C& \5 t- W2 A 3#include <stdlib.h>% ?4 |1 _; b1 G! d5 B5 K 4 5static int a = 5; 6 R0 Z0 C! ?* J. j; x- o1 [7 d 6/***************************9 |3 {" l% h4 N$ Y+ c% H0 V; [" r 7 * .c文件声明区域 8 **************************/ 9#include"module1.c"$ X" p [! R. {! W+ h 10 11/*************************** 12 * Fuction: main 13 * Author 公众号:最后一个bug) 9 N) H! ~5 s* C! M% }6 E/ M6 Y14 **************************/ 15int main(int argc, char *argv[]) { 16- ^, f. H8 U2 b1 T" X$ a) y 17 Fuction1(); 8 |8 ]# r0 J% b% q* O 18 printf("main %d\n",a);8 w/ m- b1 f) X/ N9 Z; @) I 19 printf("欢迎关注公众号:最后一个bug\n");' y5 z; z. {* |# y7 z 20 return 0;9 o/ L& T1 C% A( {6 H 21} ' r, T5 R D8 }. L J% {- w 1//FileName: Module2.c 2#include<stdio.h> 3/*************************** 4 * Fuction: Fuction1# h" {/ c1 d2 A8 K' t+ { 5 * Author 公众号:最后一个bug) 7 p+ Z1 ^% L6 y9 z1 K, ?5 R W6 **************************/ 7void Fuction1()7 G. N" ^* S, X+ f$ v" N1 l 8{ 9 printf("Run Fuction1\n"); 10 printf("Fuction1 %d\n",a); 11}
注意了!! ; F) `4 W/ `* b" T2 K6 Q o/ k9 r3 m/ o4 |/ o8 r9 g 那么之前有小伙伴说 : " static的作用域仅仅在对应的文件中 ",通过上面的多个.c文件使用静态a变量,那么这位小伙伴表述就不那么贴切了! 4、最后总结 大家在正常的开发过程中bug菌还是不建议使用#include"xxx.c",因为在我们程序的设计过程中,.h文件就是一种外部的引用接口,而.c是对应的内部实现,如果滥用#include"xxx.c"有可能造成函数等等的重复定义,同时也对调试相关程序带来一些困扰,当然如果游刃有余就没啥问题的啦。 ) E# U0 J4 Z+ C7 }+ U- `. Q 不过对于喜欢写长文件的小伙伴来说却是是福音,把一个长的.c文件分成多个.c文件,这样至少可以把不知道这种用法的同事面前秀一秀! |
微信公众号
手机版