【问题标题】:Pass an array as an argument and print the array item in C program将数组作为参数传递并在 C 程序中打印数组项
【发布时间】:2019-11-19 10:21:23
【问题描述】:

我在C程序的main方法中声明并初始化了一个数组,并定义了一个打印数组元素的方法,但是它打印了一些垃圾值而不是实际值。

我尝试了以下代码。

#include <stdio.h>

void arraySize(int arr[]);

int main() {
    int array[] = {15, 50, 34, 20, 10, 79, 100};

    arraySize(array);

    return 0;
}

void arraySize(int arr[]) {
    int i = 0;

    while(arr[i]) {
        printf("The value of arr[%d] is %d \n", i, arr[i]);
        i++;
    }
}

我得到以下输出

The value of arr[1] is 50
The value of arr[2] is 34
The value of arr[3] is 20
The value of arr[4] is 10
The value of arr[5] is 79
The value of arr[6] is 100
The value of arr[7] is 3538944
The value of arr[8] is 28
The value of arr[9] is 6422300
The value of arr[10] is 3538944
The value of arr[11] is 6422368
The value of arr[12] is 4198966
The value of arr[13] is 1
The value of arr[14] is 8263032
The value of arr[15] is 8266360
The value of arr[16] is 2
The value of arr[17] is 0

请帮助我如何使用 while 循环打印数组值并在到达记录结尾时终止循环。

【问题讨论】:

  • 您正在阅读超出数组末尾的内容。这会导致“未定义的行为”(谷歌该术语)。
  • 数组不会神奇地以 NULL 或 0 结尾。您需要在数组末尾显式添加这样的值,或者将数组大小传递给函数。
  • 编译器如何知道传递的array 的大小?使用sizeof单独传递它然后使用它。
  • @B.Balamanigandan 您更改了代码。 Previously 你在 printf 之前有 i++。这将导致数组中的第一个元素无法完全按照您显示的那样打印。我怀疑您更改代码后没有更新输出。
  • @B.Balamanigandan 您的输出与程序不匹配。请在此处发布您的下一个问题之前阅读此内容:How to Ask

标签: c arrays arguments


【解决方案1】:

数组不包含值为0的元素。所以循环的条件

while(arr[i])

相当于

while( arr[i] != 0 )

调用未定义的行为。

您还必须将要输出的元素数量传递给函数。例如

void arraySize( const int arr[], size_t n);

void arraySize( const int arr[], size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        printf("The value of arr[%zu] is %d \n", i, arr[i]);
    }
}

例如在主写中

int array[] = {15, 50, 34, 20, 10, 79, 100};
const size_t N = sizeof( array ) / sizeof( *array );

arraySize( array, N );

请记住,您无法计算函数内传递的数组的大小。编译器将数组类型的参数隐式调整为指向元素类型的指针。

也就是说这两个函数声明是等价的,并且声明了同一个函数

void arraySize( int arr[] );
void arraySize( int *arr );

请注意,输出数组元素的函数的名称arraySize 只会让代码的读者感到困惑。例如,您可以将其命名为 printArray

【讨论】:

  • @B.Balamanigandan 还有什么?该数组包含这些元素。这是您最初的做法;您尝试过这样做。
  • 我还有一个疑问,为什么我们不能计算方法级别的大小(即arraySize)?
  • @B.Balamanigandan ... 为什么你认为这是个问题?
  • 抱歉,我的意见是我的意见。
  • @B.Balamanigandan 因为传递给函数的数组被转换为指向其第一个元素的指针。所以在函数中你正在处理一个指针。
【解决方案2】:

这不起作用,因为它不能像那样找出数组大小。 int arr[] 衰减为指针,您的函数无法知道数组的大小。它会在到达数组末尾后继续运行,这是未定义的行为。可能发生的情况是它在堆栈上打印随机数据,直到遇到将0 表示为整数的内容,或者直到出现访问冲突。

while(arr[i]) 并没有像你认为的那样做。它不检查这是否有效,它只是检查arr[i] 是否具有值0(然后隐式转换为false)。巧合的是,这意味着您可以使用0 作为标记值来表示您已到达数组的末尾:

int array[] = {15, 50, 34, 20, 10, 79, 100, 0};

现在,当达到 0 并且您不再有未定义的行为时,这将停止打印。

【讨论】:

  • 好的,我接受。但是为什么它没有为从 1 到 6 的索引打印,根据您所说,它需要打印 {15, 50, 34, 20, 10, 79, 100} 并且一旦超出数组大小,它可能会打印一些垃圾值。
  • @B.Balamanigandan 第一个数组索引是 0 而不是 1。这就是你想知道的吗?
  • @B.Balamanigandan 一旦超过数组的限制,它就是未定义的行为,因此无法保证会发生什么。在尝试打印值时,打印垃圾值是 UB 的常见表现,但它也可以做一些完全不同的事情。
  • @B.Balamanigandan 您更改了代码。 Previously 你在printf 之前有i++。这将导致数组中的第一个元素无法完全按照您显示的那样打印。我怀疑您在更改代码后没有更新输出。
【解决方案3】:

改成:

#include <stdio.h>

void arraySize(int arr[], int);

int main() 
{
    int array[] = {15, 50, 34, 20, 10, 79, 100};

    arraySize(array, sizeof(array)/sizeof(array[0]));  //adding size of array as new argument

    return 0;
}

void arraySize(int arr[], int siz) 
{
    int i = 0;

    while(i<siz) 
    {
        printf("The value of arr[%d] is %d \n", i, arr[i]);
        i++;
    }
}

编译器不知道自己传递的数组的大小,因此要设置限制,您必须显式发送大小。

【讨论】:

    猜你喜欢
    • 2020-03-24
    • 2017-03-19
    • 2011-12-30
    • 2010-10-20
    • 1970-01-01
    • 2010-10-01
    相关资源
    最近更新 更多