【问题标题】:Why is sizeof not returning the correct number of elements in array?为什么 sizeof 没有返回数组中正确数量的元素?
【发布时间】:2018-08-07 22:27:03
【问题描述】:

所以为了练习,我写了一个小代码,它接受数组中可变数量的整数,然后确定最大值。

我想让程序可以从命令行运行(即 findMax 4, 5, 6, 20, 1, 3 的确切格式)。

所以考虑到argv[1] 是指向char 数组的指针,我想我可以从argv[1][0] 循环到argv[1][n]

我认为指针是我无法让我的代码工作的原因。
在第一个代码中,我使用

sizeof(arr) / sizeof(arr[0]) = # of elements in array 'arr'

正确地给了我元素的数量。
但是,当我运行时

sizeof(argv[1]) / sizeof(argv[1][0]) = always return (integer) 4

我认为我在这里使用指针是否正确,这就是为什么大小总是相同的原因?我试图取消对它们的引用(单独和一起),但它产生了更令人困惑的结果。

这是不工作的完整代码。 除了出于某种奇怪的原因,它仅在我输入 两个 数字时才有效(即 findMax.exe 2, 3 将正确确定“3”是最大的数字)。

#include <stdio.h>

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

    printf ("Finding largest value from input: %s", argv[1]);

    int size = (int)sizeof(argv[1]) / (int)sizeof(argv[1][0]);
    int x = 0;
    int next;
    int biggest = 0;

    while (x < size) {
        if (argv[1][x] != ',') {
            next = argv[1][x];
            printf("\n%c", (int)next);
            if ((int)next > biggest) {
                biggest = next;
            }   
        }
        x++;
    }
    printf("\nBiggest # is: %c", biggest);

    return 0;
}

【问题讨论】:

  • 因为argv[1] 是一个指针而不是一个数组。
  • 因为sizeof 不是这样做的。
  • sizeof 在编译时确定。 argv[1] 中的字符数在运行时确定。因此,您将永远无法在编译时知道size 的值——您必须通过查看每个字符或使用执行此操作的库函数来实际检查argv[1] 中的字符串。
  • 这就是 argc 的用途
  • @DanielPryden 如果你有一个可变长度数组sizeof 在编译时未确定。

标签: c arrays pointers argv


【解决方案1】:

argv[1]char * 类型,一个指向字符的指针。 sizeof 运算符只为您提供系统上指针的大小。 argv[1][0]char 类型,因此它的大小是 1

它适用于两个数字,因为“2,3”有四个字符(包括空终止符),恰好与您平台上指针的大小相同。

您需要做的是在运行时使用strlen 函数确定argv[1] 的长度。

int size = strlen(argv[1]);

但还有其他一些事情可能会导致问题:

如果您不向函数传递任何参数,则行为未定义,因为 argv[1] 不存在。您应该检查argc 传递了多少参数。

您所做的int 类型转换在下一个, 之前不会读取整数,正如您的示例用法所暗示的那样。

这是一个应该可以运行的程序:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int next, biggest=INT_MIN;
    char *token;

    if(argc != 2)
    {
        printf("Wrong arguments.\n");
        return -1;
    }

    char input[strlen(argv[1])+1];
    strcpy(input, argv[1]);

    printf ("Finding largest value from input: %s\n\n",argv[1]);

    token = strtok(input, ",");

    while(token)
    {
        next = atoi(token);
        if(next>biggest)
        {
            biggest = next;
        }
        token = strtok(NULL, ",");   
    }

    printf("Biggest # is: %d\n",biggest);

    return 0;
}

【讨论】:

  • 也许不如int size = strlen(argv[1]) + 1;
  • @WeatherVane int size = strlen(argv[1]) + 1; 很适合 size 的想法,但随后 next = argv[1][x]; 将最终使用 next = '\0';
  • @chux 哎呀,我希望 1 arg 所以 argc=2。看起来 op 正在用 x 遍历第一个 arg 中的字符。 (我的愚蠢建议已删除)
  • 次要:以int biggest=INT_MIN; 开头,代码可以正确报告带有"findMax -4,-5,-6" 之类的输入的“可变数量的整数”。
  • @chux 我也想过,但想坚持 OPs 方法。无论如何,如果有人想处理负值肯定会更好。我会改变我的答案,谢谢。
【解决方案2】:

实际上argv[1] 是指向char 的指针,而不是char 的数组。考虑到您平台中的指针大小为 4,char 肯定是 1 个字节,那么 4 就是这个问题的逻辑答案:

sizeof(argv[1]) / sizeof(argv[1][0])
     4          /        1

您的代码的一个主要问题是您没有解析整数。你在比较人物。在10,2 中,最大的是2

请注意,如果打算逐个字符地迭代直到结束,则根本不需要查找字符串的大小。你可以这样做,直到找到一个空值。但是,如果您确实想解析字符,这种策略可能不是最简单的。

不涉及数组或大小检查的完全不同的方法可以使用strtokstrtol 将字符串解析为标记和整数。下面是一个非常简单的实现,根本没有错误检查:

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

int
main(int argc, char **argv)
{
    int curr, max = 0;
    char *token;

    token = strtok(argv[1], ",");

    while (token != NULL) {
        curr = (int)strtol(token, (char **)NULL, 10);
        if (curr > max) max = curr;
        token = strtok(NULL, ",");
    }
    printf("The biggest integer was: %d\n", max);

    return 0;
}

【讨论】:

  • @snr 不是吗?那是什么?
  • 这是我的错。这里太晚了。对不起大家。有美好的夜晚!这都是我的!
  • @sidyll 更准确地说,当数组作为函数参数传递时,它们会衰减为指针。
猜你喜欢
  • 1970-01-01
  • 2017-02-05
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多