分配给具有不同值的参数的 C 指针参数

C pointer argument assigned to a parameter with a different value

我试图用 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,而是一个更高的地址;不明白为什么会这样。

这次通话

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时,用户可以调用空范围的函数。在这种情况下,该函数将具有未定义的行为,因为对于空范围,没有最大的元素。

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

此外,在 C 中没有函数重载,因此应该为常量和 non-constant 数组调用函数。

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

#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 + 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