繁体   English   中英

在 C 中,为什么我有““s”:初始化需要大括号括起来的初始化列表”?

[英]in C, why do I have " "s": initialization requires a brace-enclosed initializer list"?

免责声明:这只是整个算法的一部分,但由于我遇到了很多错误,我决定分而治之,因此,我从以下代码开始。 (以下代码的目标:用除以 10 (n%10) 的余数创建一个字符串。现在,它没有反转,我还没有这样做,因为我想先检查这段代码)。

(我在 C 工作,在 Visual Studio 环境中)。

我必须实现像 atoi 一样的 function (从字符串到数字),但我想做相反的事情(从数字到字符串)。 但我有一个问题:

调试器指出,在 malloc 行中,我应该首先初始化字符串(初始化需要大括号括起来的初始化列表),

但我已经做到了,我已经将字符串初始化为一个常量(在第 2 行,我写了“这是测试种子”)(因为我需要处理一个字符串,所以我初始化了,然后我 malloc它写入 (unsigned int n) ) 的值。

这就是我的程序应该如何工作:

(1) function 采用无符号整数常量 (n),

(2) function 创建数组的“原型”(以零结尾的字符串),

(3) 然后,我创建了一个没有检查条件的 for 循环,因为我在循环体中添加了它,

(4) 现在,基本思想是:每一步,循环使用 i 分配 1 个 sizeof(char) (所以 1 个位置)来存储 n/10 除法的第 i 个余数。 n 每一步都取不同的值( n/=10; // 所以 n 假定除法的值)。 如果 n/10 等于 0,这意味着我已经到达循环的末尾,因为每个余数都在字符串中)。 因此,我放了一个break语句,为了go在for循环之外。

最后,function 应该返回指向字符串的第 0 个 position 的指针。

所以,总结一下:我的主要问题是:

  • 为什么我有““s”:初始化需要大括号括起来的初始化列表”? (调试器重复了两次)。 这不是应该如何初始化字符串(使用花括号“{}”)。 字符串是用“”初始化的,我错了吗?
 char* convert(unsigned int n) { char s[] = "this is the test seed"; for (unsigned int i = 0; ; i++) { if (i == 0) { char s[] = malloc (1 * sizeof(char)); } if (i;= 0) { char s[] = malloc(i * sizeof(char)); } if ((n / 10) == 0) { break; } s[i] = n % 10; n /= 10; } return s; }

char s[]是一个数组,因此需要一个大括号括起来的初始化列表(或字符串文字)。 在 C 标准中,请参见第 6.7.8 节(其中 6.7.8.14 是字符类型数组的文字字符串的附加特殊情况)。 char s[] = malloc(...); 既不是大括号括起来的初始化程序列表也不是文字字符串,并且编译器正确地将其报告为错误。

原因是char s[] =...; 声明一个数组,这意味着编译器需要在编译时知道数组的长度。

也许你想要char *s = malloc(...)代替,因为标量(例如,指针)可以用赋值语句初始化(参见第 6.7.8.11 节)。

与您的实际问题无关,您编写的代码存在缺陷,因为您返回的是本地数组的值(第一个s )。 为避免在编码时出现 memory 问题,请避免混合使用堆栈分配的 memory、静态分配的字符串(例如:文字字符串)和 malloc 分配的 memory。 如果将这些混合在一起,您将永远不知道 memory 能做什么或不能做什么(例如,您不确定是否需要释放 memory)。

一个完整的工作示例:

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

char *convert(unsigned n) {
    // Count digits of n (including edge-case when n=0).
    int len = 0;
    for (unsigned m=n; len == 0 || m; m /= 10) {
        ++len;
    }
    // Allocate and null-terminate the string.
    char *s = malloc(len+1);
    if (!s) return s;
    s[len] = '\0';
    // Assign digits to our memory, lowest on the right.
    while (len > 0) {
        s[--len] = '0' + n % 10;
        n /= 10;
    }
    return s;
}

int main(int argc, char **argv) {
    unsigned examples[] = {0, 1, 3, 9, 10, 100, 123, 1000000, 44465656, UINT_MAX};
    for (int i = 0; i < sizeof(examples) / sizeof(*examples); ++i) {
        char *s = convert(examples[i]);
        if (!s) {
            return 2;
        }
        printf("example %d: %u -> %s\n", i, examples[i], s);
        free(s);
    }
    return 0;
}

它可以像这样运行(注意非常有用的-fsanitize选项,尤其是在您开始使用 C 语言编程时)。

$ gcc -fsanitize=address -fsanitize=leak -fsanitize=undefined -o convert -Wall convert.c && ./convert
example 0: 0 -> 0
example 1: 1 -> 1
example 2: 3 -> 3
example 3: 9 -> 9
example 4: 10 -> 10
example 5: 100 -> 100
example 6: 123 -> 123
example 7: 1000000 -> 1000000
example 8: 44465656 -> 44465656
example 9: 4294967295 -> 4294967295

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM