【问题标题】:unable to initialize array in c | warning: conversion to long unsigned from long无法在 c 中初始化数组 |警告:从 long 转换为 long unsigned
【发布时间】:2020-01-26 13:04:35
【问题描述】:

我正在尝试编写一个程序,该程序首先创建一个表示图形的二维数组(请注意,图形的维度将作为输入给出)。

我想将这个数组初始化为 0,在谷歌搜索后我发现你必须使用 memset() 来完成,因为数组的内存将从输入文件中动态分配。

以下是我目前程序的一小部分:

long int N;

int main(int argc, char *argv[]) {
    long int i;

    FILE * txt;
    txt = fopen(argv[1], "r");
    if (txt == NULL) {
        printf("There was an error trying to open the file.\n");
        return 0;
    }

    fscanf(txt, "%li", &N);

    long int graph[N][N];
    memset(graph, 0, N*N*sizeof(long int));

    return 1;
}

当我使用 gcc -Wconversion 编译它时,我收到以下警告:

警告:从“long int”转换为“long unsigned int”可能会改变 结果的符号 [-Wsign-conversion] memset(graph, 0, N*N *sizeof(long int));

我无法理解编译器在代码的哪一点尝试将 long int 转换为无符号整数。我搜了一下,只有当他们混合了不同类型的变量时,人们才会遇到同样的问题。

任何帮助将不胜感激!

---编辑---

使用help of 'Vlad from Moscow' 我能够解决上述警告(我必须将 N 更改为 size_t 类型才能正确调用 memset()),但现在我想将另一个 long int 数组初始化为 LONG_MAX 并且我得到了另一个:

memset(dist, LONG_MAX, N*sizeof(long int));

警告:隐式常量转换溢出 [-Woverflow]

【问题讨论】:

    标签: c arrays initialization overflow memset


    【解决方案1】:

    函数memset 需要size_t 类型的第三个参数。 所以将变量 N​​ 声明为

    size_t N;
    

    然后写

    fscanf(txt, "%zu", &N);
    

    第二个警告与memset调用的第二个参数有关

    memset(dist, LONG_MAX, N*sizeof(long int));
    

    期望它在函数内部的int 类型被转换为unsigned char 类型。

    这是函数声明。

    void *memset(void *s, int c, size_t n);
    

    通常该函数的唯一应用是对数组进行零初始化。

    【讨论】:

    • 感谢您的回答,对我编辑的新版本有什么想法吗? :)
    • @Vlad memset(graph, 0, sizeof(long int)*N*N); 而不是 memset(graph, 0, N*N*sizeof(long int)); 怎么样?
    • @Vlad 所以我想做的事情不能用 memset() 来完成?想用它来加快执行速度,但我想我会改用“老式的”方式......
    • @DonS 是的,对于有符号的 int 类型,memset 无法做到这一点
    • @VladfromMoscow 用memset(graph, 0, sizeof(long int)*N*N) 也不能用 size_t 数学解决它吗?
    【解决方案2】:

    size_t 可以解释为 unsigned int 或 unsigned long int;取决于机器。

    不需要使用 memset() 来用 0 填充数组,你可以把这些东西交给编译器。 只需将 0 分配给第一个元素,编译器就会将 0 分配给所有未初始化的元素!

    long int graph[N][N] = {0};
    

    你试图在错误的地方使用 memset()! memset() 以“字节方式”设置存储。

    void *memset(s,c,n) --> 将字符 c 放入前 n 个字符中 s,返回s

    注意 c 是字符而不是整数。

    那么,如何用 LONG_MAX 初始化一个数组呢?

    使用循环:

     for(long i = 0; i < N; ++i)
       dist[i] = LONG_MAX;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      • 2016-04-19
      • 2011-02-05
      • 1970-01-01
      相关资源
      最近更新 更多