首页 > 解决方案 > C结构体数组的初始化

问题描述

Unix 6 源代码。很古老。

配置文件

 struct bdevsw {
   int (*d_open)();
   int (*d_close)();
   int (*d_strategy)();
   int *d_tab;
 } bdevsw[];

conf.c

 int (*bdevsw[])(){
    &nulldev, &nulldev, &rkstrategy, &rktab,
    &nodev, &nodev, &nodev, 0,
    0
 }

我的问题为什么不初始化只是读取,

 bdevsw[] = {......}

标签: cunix

解决方案


为这个答案收集的所有信息都来自我值得信赖的狮子会评论书副本。它是非常早期的 UNIX 代码的一个很好的资源。

如果您将声明的怪物注入cdecl,您会发现它的目的是:

声明bdevsw为指向函数返回的指针数组int

因此,它根本不是代码(a),而是函数的数组定义,每个设备一个,与您的建议几乎相同。

它不在头文件中的原因可能是以下原因。


首先,该conf.c文件实际上是由自动生成mkconf,因为该文件包含给定 UNIX 系统的设备详细信息(块和字符设备,保存在bdevsw和中cdevsw)。

作为一个自动生成的文件,将数据类型的声明(在不同系统之间是一致的)和数组的定义(每个系统都会改变)分开是有意义的。该文件顶部的注释表明它和low.s是 的结果mkconf


其次,有不少 C 文件包含conf.h. 例如,bio.c(块 I/O)、sys3.c(文件系统调用)、fio.c(文件调用)和alloc.c(非常早的初始化以读取根超级块)。

所以,如果在头文件中定义了数组(大概是static为了防止双重定义),每个源文件基本上都有自己的副本,浪费了宝贵的空间。通过在 中定义它conf.c,每个人都共享一个副本。


(a)你的评论是:

初始化 stmt 中的第二个括号使它看起来像一个函数

是可以理解的,在这种情况下,它确实代表了一个函数调用。但仅限于它是指向函数的指针数组,而不是实际的函数定义。


推荐阅读