头文件与源文件中都分别存放哪些东西

    在C代码文件中,我们经常会看到两类文件:

                                        一类是:".h"文件

                                        一类是:".c"文件

   ".h"文件,就是我们常说的头文件。

   ".c"文件,就是我们常说的源代码文件。

 

   而在做开发的时候,经常不知道要把哪些东西放到".h"文件之中,又要把哪些东西放到".c"文件中。

   今天就详细介绍一下这两个文件(".h"和".c")中都应该存放写什么东西。

   首先,先介绍".h"文件。

   ".h"文件中存放的东西有:

           1.include所需要的头文件。 如 #include<linux/pid.h>

           2.宏定义。          如: #define SIZE 10;

           3.类型的定义。      如: typedef struct student{} student

           4.外部变量的声明。  如: extern struct task_struct *task;

                                   extern spinlock_t spinlock;

           5.函数的声明。      如: int sum(int a, int b


           6.static inline函数。如:static inline sum(int a, int b);

   以下是一个linux源码包中的头文件:

 
  2 //头文件说明,用于防止头文件重名
  3 #ifndef _LINUX_PID_H
  4 #define _LINUX_PID_H
  5 
  6 #include <linux/rcupdate.h>
  7 
  8 //类型定义
  9 enum pid_type
 10 {
 11     PIDTYPE_PID,
 12     PIDTYPE_PGID,
 13     PIDTYPE_SID,
 14     PIDTYPE_MAX
 15 };
 16 
 17 struct upid {
 18     /* Try to keep pid_chain in the same cacheline as nr for find_vpid */
 19     int nr;
 20     struct pid_namespace *ns;
 21     struct hlist_node pid_chain;
 22 };
 23 
 24 struct pid
 25 {
 26     atomic_t count;
 27     unsigned int level;
 28     /* lists of tasks that use this pid */
 29     struct hlist_head tasks[PIDTYPE_MAX];
 30     struct rcu_head rcu;
 31     struct upid numbers[1];
 32 };
  
 47 //外部变量的声明
 48 extern struct pid init_struct_pid;
 49 extern struct pid_namespace init_pid_ns;
 50 
 51 //外部函数声明
 52 extern void put_pid(struct pid *pid);
 53 extern struct task_struct *pid_task(struct pid *pid, enum pid_type);
 54 extern struct task_struct *get_pid_task(struct pid *pid, enum pid_type);
 55 extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type);
 56 extern void attach_pid(struct task_struct *task, enum pid_type type,
 57             struct pid *pid);
 58 extern void detach_pid(struct task_struct *task, enum pid_type);
 59 extern void change_pid(struct task_struct *task, enum pid_type,
 60             struct pid *pid);
 61 extern void transfer_pid(struct task_struct *old, struct task_struct *new,
 62              enum pid_type); 
 
 
 64 // static inline 函数
 65 static inline struct pid_namespace *ns_of_pid(struct pid *pid)
 66 {
 67     struct pid_namespace *ns = NULL;
 68     if (pid)
 69         ns = pid->numbers[pid->level].ns;
 70     return ns;
 71 }
 72 
 73 static inline pid_t pid_nr(struct pid *pid)
 74 {
 75     pid_t nr = 0;
 76     if (pid)
 77         nr = pid->numbers[0].nr;
 78     return nr;
 79 }
 
 
 81 
 82 //宏定义
 83 #define do_each_pid_task(pid, type, task)                84     do {                                 85         struct hlist_node *pos___;               86         if ((pid) != NULL)                   87             hlist_for_each_entry_rcu((task), pos___,     88                 &(pid)->tasks[type], pids[type].node) {
 89 
 90 #define while_each_pid_task(pid, type, task)                 91                 if (type == PIDTYPE_PID)         92                     break;               93             }                        94     } while (0)
 95 
 96 #define do_each_pid_thread(pid, type, task)              97     do_each_pid_task(pid, type, task) {              98         struct task_struct *tg___ = task;            99         do {
100 
101 #define while_each_pid_thread(pid, type, task)              102         } while_each_thread(tg___, task);           103         task = tg___;                       104     } while_each_pid_task(pid, type, task)
105 #endif /* _LINUX_PID_H */

  ".c"文件中存放的东西有:

                             1.需要的头文件。

                             2.全局变量。即头文件中的"extern int 变量名"声明的变量在这儿要进行定义与初始化;

                             3.只在本文件中使用的变量。即 static 变量类型

                             4.全局函数的实现。即头文件中的"extern int 函数名"声明的函数要在这儿进行实现。

                             5.局部函数的实现。即static 变量类型 函数名

      linux源码中的".c"文件:

 29 //包含的头文件
 30 #include <linux/mm.h>
 31 #include <linux/module.h>
 32 #include <linux/slab.h>
 33 #include <linux/init.h>
 34 #include <linux/rculist.h>
 35 #include <linux/bootmem.h>
 36 #include <linux/hash.h>
 37 #include <linux/pid_namespace.h>
 38 #include <linux/init_task.h>
 39 #include <linux/syscalls.h>
 40 
 41 //只在本文件中使用的宏定义
 42 #define pid_hashfn(nr, ns)   43     hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
 
 
  //定义只在本文件中使用的变量;
 46 static struct hlist_head *pid_hash;
 47 static unsigned int pidhash_shift = 4;
 48 
 49 //全局变量的声明以及初始化,其他文件也可以使用,通过#include<linux/pid.h>即可
 50 struct pid init_struct_pid = INIT_STRUCT_PID;
 51 
 52 int pid_max = PID_MAX_DEFAULT;
 53 int pid_max_min = RESERVED_PIDS + 1;
 54 int pid_max_max = PID_MAX_LIMIT;
 55 struct pid_namespace init_pid_ns = {
 56     .kref = {
 57         .refcount       = ATOMIC_INIT(2),
 58     },
 59     .pidmap = {
 60         [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
 61     },
 62     .last_pid = 0,
 63     .level = 0,
 64     .child_reaper = &init_task,
 65 };
 66 EXPORT_SYMBOL_GPL(init_pid_ns);
 
 
 
 68 //函数的实现,其他文件通过#include<linux/pid.h>就可以使用此函数;
 69 int is_container_init(struct task_struct *tsk)
 70 {
 71     int ret = 0;
 72     struct pid *pid;
 73 
 74     rcu_read_lock();
 75     pid = task_pid(tsk);
 76     if (pid != NULL && pid->numbers[pid->level].nr == 1)
 77         ret = 1;
 78     rcu_read_unlock();
 79 
 80     return ret;
 81 }
 82 EXPORT_SYMBOL(is_container_init);
 83 
 84 //只能被本文件中的其他函数使用的函数。
 85 static void free_pidmap(struct upid *upid)
 86 {
 87     int nr = upid->nr;
 88     struct pidmap *map = upid->ns->pidmap + nr / BITS_PER_PAGE;
 89     int offset = nr & BITS_PER_PAGE_MASK;
 90 
 91     clear_bit(offset, map->page);
 92     atomic_inc(&map->nr_free);
 93 }
时间: 2024-10-10 21:20:47

头文件与源文件中都分别存放哪些东西的相关文章

C/C++编程 头文件与源文件中的内容

从规模较小的程序转到比较复杂的程序,头文件与源文件中的内容组织困扰了很久,特别是头文件中该放哪些内容,到处搜索文章并进行了一次总结,如果有什么错误或者值得商榷的地方,希望大家能够不吝赐教. 引入问题: 编译模式:一个程序的源代码,可以放到不同的文件进行存放,每一个源文件都是独立的,可以分别进行编译,生成程序的时候只需要将各个目标程序进行一次连接便可以了.比如在一个文件中定义了一个函数 void a(),而另外一个文件中只有void a()的声明,如此并不影响把这个文件编译成目标文件,当一个文件中

头文件与源文件

以下内容全部是个人总结,如果有错误请指正! 在初学C++的时候,我总是彷徨于不恰当使用头文件.声明.定义.源文件而导致的各种Link错误.今天我想通过一些简单的测试,得到一些概括的,一般性的结论.(因为我没有学习过C++的编译器,所以我所以这些结论仅仅是一些根据一些现象的猜想) 实验环境:集成开发环境(Visual Studio 2017),并没有直接使用过g++的shell命令. 1. 在Visual Studio 2017 环境下,项目中的文件会被赋予不同的类型每个类型有各自的作用. 1.1

C++中头文件与源文件的作用详解

一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件―― .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 C++ 头文件,里面放的也是 C++ 的源代码. C++ 语言支持"分别编译"(separatecompilation).也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的 .cpp 文件里..cpp 文件里的东西都是相对独立的,在编译(compile)时不需要与其他文件互通

Visual Studio 中的头文件、源文件和资源文件都是什么?有什么区别??

头文件:后缀为.h,主要是定义和声明之类的,比如类的定义,常量定义源文件:后缀.cpp,主要是实现之类的,比如类方法的实现资源文件主要是你用到的一些程序代码以外的东西,比如图片之类,或者菜单.工具栏之类的定义之类

C++笔记--建立头文件与源文件

新建一个头文件 myadd.h #ifndef MYADD_H #define MYADD_H int fun_add(int a,int b); #endif 新建一个源文件 myadd.cpp #include "myadd.h" int fun_add(int a,int b) { return a+b; } 主程序: #include <iostream> #include "myadd.h" using namespace std; int m

函数实现不放在头文件的原因,及何时可以放头文件的情况

1 .引子       在平常的 C/C++ 开发中,几乎所有的人都已经习惯了把类和函数分离放置,一个 .h 的头文件里放声明,对应的 .c 或者 .cpp 中放实现.从开始接触,到熟练使用,几乎已经形成了下意识的流程.尽管这样的做法无可厚非,而且在不少情况下是相对合理甚至必须的,但我还是要给大家介绍一下把实现全部放置到头文件中的方式,给出可供大家使用的另一个选择.同时针对这一做法,也顺便说一下其优缺点以及需要注意的情况.       我是一个很喜欢简洁的人,多年以来甚至养成了这样的癖好,如果一

.c和.h文件的区别(头文件与之实现文件的的关系~ )

 .c和.h文件的区别 一个简单的问题:.c和.h文件的区别 学了几个月的C语言,反而觉得越来越不懂了.同样是子程序,可以定义在.c文件中,也可以定义在.h文件中,那这两个文件到底在用法上有什么区别呢? 2楼: 子程序不要定义在.h中. 函数定义要放在.c中,而.h只做声明.否则多引用几次,就会发生函数重复定义的错误. 3楼: .h只做声明,编译后不产生代码   4楼: 这样做目的是为了实现软件的模块化 使软件结构清晰,而且也便于别人使用你写的程序 纯粹用 C 语言语法的角度,你当然可以在 .h

设计自己的头文件

头文件一般包含1.类的定义,2.extern变量的声明, 3.函数的声明: 规则1: 头文件是用于声明的,而不是用于定义: 下面语句不应该出现在头文件中: extern int val = 10; //虽然加了extern关键字,但这仍是一个定义,因为对val进行了初始化赋值: double fica_rate; //这也是一个定义:定义了一个double型变量fica_rate, 为fica_rate分配了内存空间: 正确写法: extern doublefica_rate; extern i

预处理命令(宏定义,条件编译,头文件)

宏定义 <1>不带参数宏定义:#define PI 3.1415926 <2>带参数的宏定义: #define PI  3.1415926 #define S(r)  (PI*(r)*(r)) void main(){float  a=2,area;area=S(a); } 用宏可以得到几个结果: #define CIRCLE(R,L,S,V)  L=2*PI*(R);S=PI*(R)*(R);V=4.0/3.0*PI*(R)*(R)*(R) void main(){float r