【问题标题】:C pointer argument assigned to a parameter with a different value分配给具有不同值的参数的 C 指针参数
【发布时间】:2020-12-29 00:21:44
【问题描述】:

我试图用 C 语言编写一个看似微不足道的函数来获取整数数组中的最大值。我正在尝试使用指针来获得更好的理解。 (我知道如何通过数组的大小来做到这一点,问题不是如何以另一种方式做到这一点)

#include <stdio.h>

int gimme_largest(int *, int *);

int main(void)
{
  int arr[] = {1, 22, 3, 44, 5};
  int largest;

  printf("In main, arr:\t\t\t %p \n", arr);
  printf("In main, arr + sizeof(arr):\t %p\n", arr + 5);
  putchar('\n');

  largest = gimme_largest(arr, arr + sizeof(arr));
  // printf("\n\nThe largest is %d", largest);

  return 0;
}

int gimme_largest(int *a, int *lastPlusOne)
{
  int largest = *a; // let's assume the first element is the largest one

  printf("In gimme_largest, a:\t\t %p\n", a);
  printf("In gimme_largest, a + 5:\t %p\n", a + 5);
  printf("In gimme_largest, lastPlusOne:\t %p\n", lastPlusOne);

  while (a < lastPlusOne) {
    if (*a > largest)
      largest = *a;
    a++;
  }

  return largest;
}

问题是lastPlusOne在调用函数中不等于a + 5,而是更高的地址;不明白为什么会这样。

【问题讨论】:

  • arr + sizeof(arr) 错误。
  • sizeof(arr) 是多少?

标签: arrays c pointers pointer-arithmetic function-definition


【解决方案1】:

这个电话

largest = gimme_largest(arr, arr + sizeof(arr));

无效。 sizeof( arr ) 在您的程序中等于 5 * sizeof( int ) 而对于正确的指针算法,您只需要使用数组中的元素数。

那就是应该有

largest = gimme_largest(arr, arr + sizeof(arr) / sizeof( *arr ) );

因此,表达式sizeof(arr) / sizeof( *arr ) 等于您在此 printf 调用中使用的值 5

  printf("In main, arr + sizeof(arr):\t %p\n", arr + 5);

注意当a等于lastPlusOne时,用户可以调用空范围的函数。在这种情况下,函数将具有未定义的行为,因为对于空范围,没有最大的元素。

函数应该返回一个指向最大元素的指针。

与 C 中一样,没有函数重载,因此应该为常量和非常量数组调用该函数。

这是一个演示程序,展示了如何定义函数。

#include <stdio.h>

int * gimme_largest( const int *first, const int *last )
{
    const int *largest = first;
    
    if ( first != last )
    {
        while ( ++first != last )
        {
            if ( *largest < *first ) largest = first;
        }
    }
    
    return ( int * )largest;
}

int main(void) 
{
    int arr[] = {1, 22, 3, 44, 5};
    const size_t N = sizeof( arr ) / sizeof( *arr );
    
    int *largest = gimme_largest( arr, arr + N );
    
    printf( "The largest number is %d\n", *largest );
    
    return 0;
}

程序输出是

The largest number is 44

【讨论】:

  • 嗯,是的,*arr 指向第一个 int 元素的值,所以sizeof(*arr) 等价于sizeof (int)。我更喜欢这个:arr + sizeof(arr) / sizeof(int),但我想如果我改变数组的类型,你的解决方案会更灵活。
  • @BobbyWan-Kenobi 我用演示程序附加了我的答案。
【解决方案2】:

要获取数组的结束地址,可以通过arr + sizeof(arr) / sizeof(arr[0])

#include <stdio.h>

int gimme_largest(int *, int *);

 int main(void)
{
 int arr[] = {1, 22, 3, 44, 5};
  int largest;

  printf("In main, arr:\t\t\t %p \n", arr);
  printf("In main, arr + sizeof(arr):\t %p\n", arr + 5);
  putchar('\n');

  largest = gimme_largest(arr, arr + sizeof(arr) / sizeof(arr[0]));
  printf("\n\nThe largest is %d", largest);

  return 0;
  }

int gimme_largest(int *a, int *lastPlusOne)
{
 int largest = *a; // let's assume the first element is the largest one

  printf("In gimme_largest, a:\t\t %p\n", a);
  printf("In gimme_largest, a + 5:\t %p\n", a + 5);
  printf("In gimme_largest, lastPlusOne:\t %p\n", lastPlusOne);

  while (a < lastPlusOne) {
    if (*a > largest)
       largest = *a;
    a++;
  }

 return largest;
}

输出:

In main, arr:                    000000000062FE00
In main, arr + sizeof(arr):      000000000062FE14

In gimme_largest, a:             000000000062FE00
In gimme_largest, a + 5:         000000000062FE14
In gimme_largest, lastPlusOne:   000000000062FE14


The largest is 44

【讨论】:

  • @ryyker 实际上是arr + sizeof(arr) / sizeof(arr[0])sizeof(arr) / sizeof(arr[0]) 我们只得到数组的长度。而gimme_largest 期望第二个参数是数组的结束地址,这是因为在方法中提问者会这样做while (a &lt; lastPlusOne) {
  • Emm...这是while (a &lt; lastPlusOne) {....},你可能想再检查一下,它正在比较指针地址。
  • 刚刚做了。我错了,你是对的。我想我需要更多的咖啡 :) 我会把我生病的马拉出比赛。我会清理我的 cmets...
猜你喜欢
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 2014-11-27
  • 1970-01-01
相关资源
最近更新 更多