【问题标题】:Applying sizeof() to an element in const char *array[]将 sizeof() 应用于 const char *array[] 中的元素
【发布时间】:2020-10-20 00:07:29
【问题描述】:

这很好用:

#include <unistd.h>

const char error[] = “Not enough arguments\n”;

int main(void)
{
    write(2, error, sizeof(error));
    return (0);
}

Output: Not enough arguments

但是在这种情况下 sizeof 会返回指针的大小:


#include <unistd.h>

const char *error[] = {
    "Not enough arguments\n",
    "Malloc failed\n",
    "Etc...\n",
    NULL
};

int main(void)
{
    int i = 0;

    while (error[i])
    {
        write(2, error[i], sizeof(error[i]));
        i++;
    }
    return (0);
}

Output: Not enouMalloc fEtc...

显然,我可以只使用 strlen 或 printf 或大量其他解决方案。但我主要想知道 sizeof() 是否可行,但没有明确声明其大小(例如 char error[4][12])。

【问题讨论】:

  • 不,这是不可能的。 error 的元素是指针,而不是数组。
  • 对于第一个例子:几乎完美,或+1字节; sizeof(error) 返回 22,覆盖数组显示的 21 个字节 + 空终止符;尝试将输出通过管道传输到 cat -vxxd -g 1

标签: c


【解决方案1】:

sizeof 是一个运算符(不是函数),它在编译时而不是在运行时计算其操作数(可变长度数组除外)。数组中元素的类型是char*,因此您会得到该结果。

请注意,sizeof 的编译时间限制有一个例外。 C99 和 Cxx11 允许在运行时为变长数组计算 sizeof。

【讨论】:

  • 如果在编译时评估sizeof#include &lt;stdio.h&gt; / int main(void) {int n; scanf("%d", &amp;n); int a[n]; printf("%zu\n", sizeof a); } 是如何工作的?
  • @EricPostpischil 在 c99 和 cpp 11 中对于可变长度数组存在异常。
  • 所以它并不总是在编译时进行评估?
【解决方案2】:

这有点可能,但并不简单。您可以定义如下结构:

struct error_st {
    char * msg;
    size_t msg_len;
}

制作如下宏:

#define ERROR(msg) {msg, sizeof(msg)}

那么你的错误列表就变成了:

struct error_st error_list[] = {
    ERROR("Not enough arguments\n"),
    ERROR("Malloc failed\n"),
    ERROR("Etc...\n"),
    {NULL, 0}
};

用法是:

write(2, error_list[i].msg, error_list[i].msg_len);

如果您永远不会在其他地方使用它们,那么使用额外的结构和宏以及额外的字段可能不值得。您可以将 struct 作为声明的一部分,但我经常发现我最终需要将其分开,而您仍然留下了那个额外的宏:

#define ERROR(msg) {msg, sizeof(msg)}
struct error_st {
    char * msg;
    size_t msg_len;
} error_list[] = {
    ERROR("Not enough arguments\n"),
    ERROR("Malloc failed\n"),
    ERROR("Etc...\n"),
    {NULL, 0}
};

【讨论】:

  • 类似于 OP 的第一个示例,sizeof() 字符串文字说明了空终止符;此示例中的每个 write() 输出将在末尾包含一个空字节;检查cat -vxxd -g 1
  • 这太聪明了,我喜欢它!
  • 你是对的。这是您复制时想要的大小,而不是写入时想要的大小。您可以将宏更改为存储 sizeof()-1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2012-07-10
  • 1970-01-01
  • 2021-01-04
  • 2012-01-29
  • 2014-05-05
相关资源
最近更新 更多