【问题标题】:invalid type argument of unary '*' (have 'int') lowest element in array一元'*'的无效类型参数(有'int')数组中的最低元素
【发布时间】:2016-01-30 08:01:59
【问题描述】:

我想使用函数lowest() 查找数组中的最低元素。但是这个程序不起作用。它显示错误

一元'*'的无效类型参数(有'int')

代码如下:

#include <stdio.h>

int lowest(int *j, int n) { //For finding the lowest element
    int i, temp, tempAdd;
    for (i = 0; i < n; i++) {
        if (temp > *(j + i))
            temp = *(j + i);
            tempAdd = j + i;
    }
    return tempAdd; //Sends the address of the lowest element
}

int main() {
    int n;
    printf("Enter the number of inputs: ");
    scanf("%d", &n);

    int arr[n], i;

    for (i = 0; i < n; i++) {
        printf("\nEnter element no. %d: ", i + 1);
        scanf("%d", &arr[i]);
    }

    for (i = 0; i < n; i++) {
        printf("Element no. %d is %d with the address %d.\n", i + 1, *(arr + i), arr + i);
    }

    int low = lowest(arr, n); //Saves the address of the lowest element.
    printf("\nThe Lowest element in the list is %d with address %d.", *low, low); //Error occurs
    return 0;
}

【问题讨论】:

  • 如果你想返回最小元素的地址,你的“lowest”函数应该有返回类型int *。但它有int
  • 1) tempAdd = j + i; 您正在尝试为整数分配地址。 2)您没有为 temp 分配任何值。因此,如果if(temp &gt; *(j + i)),我们无法预测第一次会有什么值
  • 尚不清楚这是 C 还是 C++ 问题。不要用两个标签来标记您的问题,因为它们是不同的语言。
  • @Archimaredes 在这些情况下,我切换到“c-ish c++”模式;)
  • 问题:为什么有 2 票反对。同意这个问题对 SO 的未来用户没有太大的价值。但这个问题在任何其他方面都不缺乏恕我直言。那么为什么要投反对票呢?

标签: c++ c unary-operator invalid-argument


【解决方案1】:

你的函数lowest有问题:

int lowest(int *j, int n) { //For finding the lowest element
    int i, temp, tempAdd;
    for(i = 0; i < n; i++) {
        if(temp > *(j + i))
            temp = *(j + i);
            tempAdd = j + i;
    }

    return tempAdd; //Sends the address of the lowest element
}
  • 您忘记了if 块周围的大括号。缩进不决定 C 中的块结构。
  • 语义不一致:将索引返回到最低元素,但将tempAdd 设置为j + i,这是指向最低元素的指针。
  • 你没有初始化temp,也没有初始化tempAdd。行为未定义。
  • 将指针命名为j 会造成混淆,j 通常指定一个整数索引。使用p

这是一个更简单的版本:

int lowest(int *p, int n) { //For finding the lowest element
    int i, tempAdd = 0;
    for (i = 1; i < n; i++) {
        if (p[i] < p[tempAdd]) {
            tempAdd = i;
        }
    }
    //Return the index of the lowest element
    return tempAdd;
}

在main中,你应该修改代码,因为low不是一个指针:

printf("\nThe Lowest element in the list is %d with address %d.",
       arr[low], &arr[low]);

【讨论】:

  • 一开始没有注意到缺少的大括号。我是一个“卷发在前面”的人,不能很好地阅读那种“后面卷发”的风格。
  • @BitTickler: 大括号单独一行 往往会产生更多的代码行,这在 StackOverflow 上不是很愉快,因为它经常导致代码窗格滚动。 命令语句末尾的大括号最初是由 K&R 以其原始样式(函数体除外)以及间距规则设计的。
  • 我像20年前一样采用前面的卷发并一直坚持下去的主要原因是事实,那就是cmets没有空间了。如果条件语句的注释突然出现在块内,如果您在末尾使用括号,这有点让我烦恼。 if(x &lt; 0) // test for valid argument \n {...} 看起来像 if(x &lt; 0) { // test for valid argument \n...} 并且看起来注释描述了块的作用,而不是语句。
  • @BitTickler:这个评论问题对于else if 块来说是真实的,但对于孤立的if 块,您可以将评论移到if 上方单独一行。
【解决方案2】:
  • 打印地址可以使用%p,如下。

    printf("\nThe Lowest element in the list is %d with address %p.", low, low);
    

【讨论】:

    【解决方案3】:
    #include<stdio.h>
    
    int *lowest(int *j, int n) { //For finding the lowest element
       int i, temp;
       int *tempAdd;
       temp=*j;
       tempAdd=j;
       for(i = 0; i < n; i++) {
        if(temp > *(j + i)){
            temp = *(j + i);
            tempAdd = j + i;
        }
       }
       return tempAdd; //Sends the address of the lowest element
    }
    

    除此之外,以下行 int low = lowest(arr, n);int *low = lowest(arr, n);

    【讨论】:

      【解决方案4】:

      lowest 函数应该是:

      int *lowest(int *j, int n) { //For finding the lowest element
          int i, temp = *j;
          int *tempAdd = NULL;
          for(i = 0; i < n; i++) {
              if(temp > *(j + i))
                  temp = *(j + i);
                  tempAdd = j + i;
          }
      
          return tempAdd; //Sends the address of the lowest element
      }
      

      在您的main 函数中:使用int *low 代替int low 并使用%p 显示变量地址。

      【讨论】:

      • 离开 temp 未初始化会产生未定义的行为。变量未默认初始化为 0 或其他值。
      • 哎呀,我错了!我在 g++ 下运行代码,它没有显示任何警告。我认为在这种情况下temp 应该是*j
      【解决方案5】:

      这里是固定函数的第一次迭代。它仍然不是我写的 100%,而是限制自己解决问题的问题。

      由于要返回地址,所以我调整了返回类型以及变量tempAdd的类型

      int* lowest(int *j, int n) { //For finding the lowest element
          int i, temp;
          int *tempAdd;
          for(i = 0; i < n; i++) {
              if(temp > *(j + i)) {
                  temp = *(j + i);
                  tempAdd = j + i;
              }
          }
      
          return tempAdd; //Sends the address of the lowest element
      }
      

      例如,对于参数n = 0,如果不对函数进行进一步更改,则函数的返回值将是未定义的。

      由于变量temp也没有初始初始化,因此返回的地址也可能是未定义的,以防数组的任何成员都小于变量temp的(随机)值。

      这里是一个更强大的版本:

      int* lowest(int *j, int n) { //For finding the lowest element
          if( 0 == n ) return NULL; // empty arrays have no smallest element!
          int i;
          int temp = j[0]; // instead of using pointer arithmetic you can also use this syntax.
          int *tempAdd = j; // initially the first element is allegedly the smallest...
          for(i = 1; i < n; i++) // loop starts at index 1 now!
          {
              if(temp > *(j + i)) {
                  temp = *(j + i);
                  tempAdd = j + i;
              }
          }
      
          return tempAdd; //Sends the address of the lowest element
      }
      

      你的函数main() 也有它的问题。您不能创建一个动态大小的自动(堆栈定位)数组,这是您尝试的。相反,如果您想向用户查询数组的大小,则必须改用基于堆的数组。或者您将查询一个大小,该大小小于或等于您的基于堆栈的数组的任意选择的固定大小。

      int main() {
          int n = 0;
          printf("Enter the number of inputs (1..500): ");
          scanf("%d", &n);
      
          if( n < 1 || n > 500 ) {
              puts("Invalid input.");
              return -1;
          }
      
          int arr[500]; // 500 was chosen because most likely no one is crazy enough to manually type in more values by hand ;)
          int i;
      
          for(i = 0; i < n; i++) {
              printf("\nEnter element no. %d: ", i + 1);
              scanf("%d", &arr[i]);
          }
      
          for(i = 0; i < n; i++) {
              printf("Element no. %d is %d with the address %d.\n", i + 1, *(arr + i), arr + i);
          }
      
          int * low = lowest(arr, n); //Saves the address of the lowest element.
          printf("\nThe Lowest element in the list is %d with address %p.", *low, low);    //Error occurs
          return 0;
      }
      

      还将指针的格式更改为“%p”。 还将low 的类型从int 更改为int *

      最后同样重要的是,如果您允许 0 数组大小,您必须进一步更改 main()。为什么?因为在你的 printf 中你写了...,*low,...。由于在 n = 0 的情况下最低()将返回 NULL,因此您将取消引用 NULL 指针,这会导致严重的运行时错误。

      从设计的角度来看,最终,在最低()中返回地址似乎破坏了抽象级别,这与您传入数组长度的事实有关。基本上,你混合了两种风格。

      1. STL 样式为:int * lowest( int *begin, int * end )
      2. 复古风格为:int lowestIndex( int *arr, int n)

      第二个版本,虽然会有一个问题,你不能表达一个“没有结果”的结果。例如,如果数组大小为 0 或其他无效参数被传递给函数。因此,人们通常会这样做:

      1. bool lowestIndex( int * arr, int n, int *result )

      ...其中返回值表示成功,结果内容只有在返回值为true时才有效。

      【讨论】:

        猜你喜欢
        • 2021-10-15
        • 2011-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-20
        • 1970-01-01
        相关资源
        最近更新 更多