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

问题描述

我试图用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时,用户可以在空范围内调用该函数。在这种情况下,该函数将具有不确定的行为,因为对于空范围,没有最大的elemenet。

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

同样在C语言中也没有函数重载,因此应为常量和非常量数组调用该函数。

这里是一个演示程序,显示了如何定义functipon。

#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,5};
  int largest;

  printf("In main,arr:\t\t\t %p \n",arr);
  printf("In main,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