[C] dirent.h库函数以及extern语法的介绍

问题前导

我在读《Unix环境高级编程》的第一章,其中给出了一个Unix环境下 ls 命令的简单例子:

#include 
#include "apue.h"

int 
main(int argc, char *argv[]) 
{
    DIR             *dp;
    struct dirent   *dirp;

    if (agrc != 2)
        err_quit("usage: ls directory_name");

    if ((dp = opendir(argv[1])) == NULL)
        err_sys("Can't open %s", argv[1]);

    while ((dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);

    closedir(dp);

    exit(0);

}

apue.h 这个头文件是作者写的常用工具,具体可在网上搜索下载(书第三版)。

库文件dirent.h提供文件夹下目录内容的结构体,一般在Unix系统下/usr/include/目录中,有opendir, readdir, closedir等库函数。

浏览此头文件,发现在宏中有如下语法:

#ifndef _DIRENT_H_
#define _DIRENT_H_

// ......

#ifdef __cplusplus
extern "C" {
#endif

struct dirent
{
    long        d_ino;      /* Always zero. */
    unsigned short  d_reclen;   /* Always zero. */
    unsigned short  d_namlen;   /* Length of name in d_name. */
    char        d_name[260]; /* [FILENAME_MAX] */ /* File name. */
};

// ......

#ifdef  __cplusplus
}
#endif

#endif  /* Not _DIRENT_H_ */

extern "C"这种语法到底有什么作用呢?

extern 语法详解

C中extern声明的变量为全局变量,程序员写的时候可以不加,编译器会默认加上。但如果A文件引用H文件中的全局变量,那么H文件的变量要用extern声明。
extern声明的全局变量可以在任何地方引用,全局变量只能定义一次,否则会出错。

extern int num; 只是声明了一个变量,但是没有定义变量,并没有给变量分配内存。

编译阶段,如果模块A调用了模块H中的全局函数,如果extern声明的,在编译阶段虽然找不到模块H中的函数,但是不会报错。其会在链接阶段从模块H编译生成的目标代码中找到此函数。

extern “C” C++调用C代码

C++对全局函数的处理和C有所不同,C++是OOP语言,而C是过程式,C++支持函数重载,而C不支持, C在编译的时候不会带上函数参数类型。extern "C" 的作用就是针对C++的代码能够调用C代码,加上此语句后编译器会按C语言进行编译。

提一下常量(宏)

#define NUMBER 20 这类语法称为常量、宏,按照惯例名称大写。这种写法的好处是程序中多次出现使用同一个值的变量,将来要修改只需要修改宏。
值得注意的是,这种语法并不是表达式,而是编译时代入法(compile-time substitution), 当程序运行时,所有的替代已经完成,这样定义的常量被称为明显常量(manifest constant)。

解释:函数重载

C++运行在同一个作用域内声明几个功能类似的同名函数,但是同名函数的形式参数不同(类型、顺序、个数)肯定得不同。

举例:

模块 common.h

#ifndef _EXT_VAR
#define _EXT_VAR
int fun(int a, float b);
#endif

模块 a.cpp 引用 common.h

#include "moduleH.h"
fun(1, 1.2);

链接阶段,编译器会从模块common.h中找类似 _fun_int_float 的符号。

如果使用了 extern "C" 则按照C语言的形式编译,链接器会寻找未经修改的 _fun 符号名。

相关链接
C static 语法

你可能感兴趣的:(C)