无法在 c 中初始化数组 |警告:从 long 转换为 long unsigned

Posted

技术标签:

【中文标题】无法在 c 中初始化数组 |警告:从 long 转换为 long unsigned【英文标题】:unable to initialize array in c | warning: conversion to long unsigned from long 【发布时间】: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]

【问题讨论】:

【参考方案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;

【讨论】:

以上是关于无法在 c 中初始化数组 |警告:从 long 转换为 long unsigned的主要内容,如果未能解决你的问题,请参考以下文章

C/C++基本问题:字符串转化为long型数字

在 C 中将多维数组作为参数传递

C# 使用 lat/long 数组计算多个曲率

在 C 中给出 unsigned long long 变量值的警告

在C中初始化字符串数组

可变数组怎么初始化(可变大小的对象不能被初始化)?