指针数组初始化,不常见啊

        今天无意间看到这样一段代码,因为还是第一次看到,这是glibc库里的代码,写出来分享一下:

#ifndef ERR_MAP
# define ERR_MAP(n) n
#endif
const char *const _sys_errlist_internal[] =
  {
#define _S(n, str)         [ERR_MAP(n)] = str,
#include <errlist.h>
#undef _S
  };

        这里很明显定义了一个指针数组,也就是首先 _sys_errlist_internal 是一个数组,并且这个数组里元素都是指针,所以它是一个指针数组毫无疑问。这里比较奇怪的是初始化方式,即 [n] = str。一般我们指针数组是这样初始化的:

const char *const errlist_internal[] = 
{
    "Operation not premitted",
    "No such file or directry",
    "I/O error"
};

        而像这样的初始化方式也是合法的,可能 C 语言所有类型的数组都支持这样初始化:

const char *const errlist_internal[] = 
{
    [0] = "Operation not premitted",
    [2] = "No such file or directry",
    [5] = "I/O error"
};

 因为没有指定数组大小,所以这样初始化数组大小是多少呢?从 C 语言数组类型知识点我们应该能猜出来,数组大小应该是 6,即包含 6 个元素。

#include <stdio.h>
#include <stdlib.h>

const char *const errlist_internal[] = 
{
    [0] = "Operation not premitted",
    [2] = "No such file or directry",
    [5] = "I/O error"
};


int main()
{
    size_t num = sizeof(errlist_internal)/sizeof(errlist_internal[0]);
    printf("number of list is %lu\n", num);
    
    size_t i =  0;

    for(; i < num; i++)
    {
        printf("errlist_internal[%lu] = %s\n", i, errlist_internal[i]);
    }

    return 0;
}

所以这种初始化方式应该是指定元素的初始化方式,未初始化到的元素是空的(指针类型时是null,其他类型未验证)。 所以像 glibc 库里这个代码,预编译出来应该类似这样的:

#include <stdio.h>
#include <stdlib.h>

#ifndef ERR_MAP
# define ERR_MAP(n) n
#endif
const char *const _sys_errlist_internal[] =
  {
#define _S(n, str)         [ERR_MAP(n)] = str,
#include "errlist.h"
#undef _S
  };


int main()
{
    size_t num = sizeof(_sys_errlist_internal)/sizeof(_sys_errlist_internal[0]);
    printf("number of list is %lu\n", num);
    
    size_t i =  0;

    for(; i < num; i++)
    {
        printf("_sys_errlist_internal[%lu] = %s\n", i, _sys_errlist_internal[i]);
    }
    
    return 0;
}

errlist.h

_S(1, "Operation not permitted")
_S(2, "No such file or directory")

预编译出来是这样的:

在 errlist.h 头文件里使用了宏定义,然后完成对指针数组的初始化。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值