【问题标题】:Qsort array | warning: initialization discards qualifiers from pointer target typeQsort 数组 |警告:初始化会丢弃来自指针目标类型的限定符
【发布时间】:2016-11-03 12:58:58
【问题描述】:

我正在 GCC 中编译这个程序,使用 Wall 命令,它看起来很清楚。但是我的大学在线平台给出了编译时错误

9.c:在函数“compare_int”中: 9.c:8:警告:初始化从指针目标类型中丢弃限定符 9.c:9:警告:初始化会丢弃来自指针目标类型的限定符

这是代码

#include <stdio.h>
#include <stdlib.h>
#define MAX 1000

int c=0;

int compare_int(const void *pa, const void *pb) {
  const int ((*a)[1]) = pa;
  const int ((*b)[1]) = pb;
  if ( (*a)[0] < (*b)[0] ) return -1;
  if ( (*a)[0] > (*b)[0] ) return +1;
  return 0;
}

void check(int m, int lastNum, int startIndex, int v[][2], int n){
  if (lastNum >= m) printf("%d\n", c);
  else{
    int i,max=0;
    for (i=startIndex;v[i][0]<=lastNum;i++){
      if (v[i][0] <= lastNum)
    if (v[i][1] > max) max = v[i][1];
    }
    c++;
    check(m, max, i,v, n);
  }
}

int main(){
  int m,n,i;
  int line[MAX][2];
  scanf("%d", &m);
  scanf("%d", &n);
  for (i=0;i<n;i++){
    scanf("%d %d", &line[i][0], &line [i][1]);
  }
  qsort(line, n, sizeof line[0], compare_int);
  check(m, 0, 0, line, n); 
  return 0;
}

该程序应该读取 2 个数字。第一个是从 0 开始的路径长度,第二个是可以填充它的对数(未排序)。然后使用贪心算法,它必须找到它需要多少段来填充它。这里的问题是用对快速排序矩阵,显然它有一些指针错误但我找不到这里有什么问题......我想它有点基本但我根本无法理解。

请帮忙!

【问题讨论】:

  • 6 5 0 2 3 5 4 6 3 8 2 4 3【下1(进程12909)正常退出】
  • 是的,我使用了 gdb,它运行良好。

标签: c arrays pointers qsort


【解决方案1】:

编译器抱怨此片段中局部变量 ab 的初始化:

int compare_int(const void *pa, const void *pb) {
  const int ((*a)[1]) = pa;
  const int ((*b)[1]) = pb;

编译器是对的。大部分。

考虑变量aCdecl 对其声明的解释如下:

将 a 声明为指向 const int 的数组 1 的指针

特别注意不是a本身就是const(没有办法声明数组const);相反,a元素const。这是一个没有太大区别的区别,除了一个挑剔的编译器观察到函数参数pa被声明为指向const对象的指针,而a被声明为指向非const对象的指针,因此将前者分配给后者会(技术上)失去const-ness。

最好的解决办法可能就是不要再那么聪明了。为什么要将ab 声明为指向单元素数组的指针,而重点是比较它们指向的对象(如ints)?您必须在局部变量声明以及使用这些值的任何地方推出棘手的语法。我会这样做:

int compare_int(const void *pa, const void *pb) {
   int a = *(const int *)pa;
   int b = *(const int *)pb;

   if ( a < b ) return -1;
   // ...

【讨论】:

  • 成功了,谢谢!我不太确定 compare_int 函数。我尝试了很多“按列排序”二维数组,但它不起作用。那段代码是在网上找到的,但你的代码更简单,更容易阅读。
  • 由于严格的别名,您的解决方案会导致未定义的行为。类型 int* 和 int(*)[2] 不兼容。
  • @2501,你说得对,int *int(*)[2] 是不兼容的类型。我没有仔细看qsort() 调用,而是专注于比较功能。然而,这还不足以产生严格的混叠违规。如果pa(例如)指向int[2],那么它必然指向该数组的第一个元素。将pa 转换为const int * 并取消引用它会通过兼容类型的左值访问int
  • 是的,我同意,6.5.7 提到了聚合类型。
  • 嗨,我正在重温这篇文章。聚合类型的别名规则在这里不适用,因为在这种情况下 int 用作左值,而不是数组(聚合)。幸运的是没有发生严格的别名,因为转换后的指针确实指向一个 int。
猜你喜欢
  • 2011-01-19
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
  • 1970-01-01
相关资源
最近更新 更多