gpt4 book ai didi

c - 何时转换 size_t

转载 作者:行者123 更新时间:2023-12-02 09:32:42 28 4
gpt4 key购买 nike

当其他数据类型如 intunsigned long intunsigned long long int 存在于程序中。我试图最低限度地说明我的困惑。想象一下我使用的程序

void *calloc(size_t nmemb, size_t size)

分配一个数组(一维或多维)。让对 calloc() 的调用依赖于 nrowsizeof(unsigned long int)sizeof(unsigned long int) 显然没问题,因为它返回 size_t。但是让 nrow 使其需要具有 unsigned long int 类型。在这种情况下我该怎么办?我是否在对 calloc() 的调用中将 nrowunsigned long int 转换为 size_t

另一种情况是

char *fgets(char *s, int size, FILE *stream)

fgets() 期望类型 int 作为其第二个参数。但是,如果我将数组传递给它,比如说 save,因为它是第一个参数并使用 sizeof(save) 来传递数组的大小?我是否将对 sizeof() 的调用转换为 int?这会很危险,因为 int 不能保证包含 sizeof() 的所有可能返回。

这两种情况我该怎么办?强制转换,还是忽略来自 splint 等工具的可能警告?

这是一个关于 calloc() 的示例(为了清楚起见,我明确省略了错误检查!):

long int **arr;
unsigned long int mrow;
unsigned long int ncol;

arr = calloc(mrow, sizeof(long int *));

for(i = 0; i < mrow; i++) {
arr[i] = calloc(ncol, sizeof(long int));
}

这是 fgets() 的示例(为清楚起见,再次省略了错误处理!):

char save[22];
char *ptr_save;
unsigned long int mrow
if (fgets(save, sizeof(save), stdin) != NULL) {
save[strcspn(save, "\n")] = '\0';
mrow = strtoul(save, &ptr_save, 10);
}

最佳答案

I'm a little confused as how to use size_t when other data types like int, unsigned long int and unsigned long long int are present in a program.

忽略警告绝不是一个好主意。警告可以将您的注意力引导到可能有问题的代码区域。最好花几分钟时间来理解警告告诉您的内容 - 并修复它,然后当您遇到极端情况并偶然发现未定义的行为时再接受它。

size_t 本身只是一种与其他数据类型一样的数据类型。虽然它可以变化,但它通常只是一个 unsigned int 覆盖可以由 int 表示的正值范围,包括 0 (类型大小旨在跨平台保持一致,每个平台上的实际字节可能不同)。您选择的数据类型是编程的基本和基本部分。您可以根据变量可以表示的值范围(或应限制为表示)选择类型。因此,如果您要处理的任何内容不能为负数,那么 unsignedsize_t 是正确的选择。然后,该选择允许编译器帮助识别您的代码会导致违反的区域。

当你编译时启用警告(例如-Wall -Wextra),你应该在每次编译时使用,你会被警告你的数据类型使用中可能发生的冲突。 (即 signedunsigned 值之间的比较等...)这些是重要!

几乎所有现代 x86 和 x86_64 计算机都使用 twos-compliment 表示符号值。简单来说,这意味着如果有符号数的最左边位是1,则该值为negative。在混合/类型转换或比较不同类型的数字时,您可能会陷入微妙的陷阱。如果您选择将 unsigned 数字转换为 signed 数字并且该数字恰好填充了最高有效位,那么您的大数字就变成了一个非常小的数字。

What should I do in these two cases? Cast, or just ignore possible warnings...

每次遇到来自编译器的警告时,您都会按照自己的方式行事。您分析导致警告的原因,然后修复它(或者如果您无法修复它 - (即来自您无权访问的某个库) - 您充分理解警告,您可以做出明智的决定,不要理会它,因为你知道你不会遇到任何会导致未定义行为的极端情况。

在您的示例中(虽然它们都不应该产生警告,但它们可能在某些编译器上):

arr = calloc (mrow, sizeof(long int *));

sizeof(long int *)的范围是多少?嗯 - 这是指针大小的范围。那么,那是什么? (x86 上的 4 bytesx86_64 上的 8 bytes)。所以值的范围是 4-8,是的,如果需要,可以通过强制转换为 size_t 来正确修复,或者更好的是:

arr = calloc (mrow, sizeof *arr);

看下一个例子:

char save[22];
...
fgets(save, sizeof(save), stdin)

这里 sizeof save 的可能范围是多少?从 22 - 22。所以是的,如果产生警告,提示 sizeof 返回 long unsigned 并且 fgets 调用 int , 22 可以转换为 int

关于c - 何时转换 size_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31093177/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com