排序功能导致的细分错误

时间:2019-08-03 10:37:35

标签: c sorting pointers

我的代码有问题。尝试调用函数sort_array时,出现错误“分段故障核心已转储” 任何人都可以帮助和感谢。

#include <stdio.h>
#define SIZE (40)

void sort_array(unsigned char *arr[],int n)
{
    unsigned char tmp;
    for (int i=0;i<n;i++)
    {
         for(int j=i+1;j<n;j++)
         {
             if(arr[j]>arr[i])
             {
                tmp=*arr[i];
                *arr[i]=*arr[j];
                *arr[j]=tmp;
             }
         }
    }
}
int main() {

  unsigned char test[SIZE] = { 34, 201, 190, 154,   8, 194,   2,   6,
                              114, 88,   45,  76, 123,  87,  25,  23,
                              200, 122, 150, 90,   92,  87, 177, 244,
                              201,   6,  12,  60,   8,   2,   5,  67,
                                7,  87, 250, 230,  99,   3, 100,  90};

  sort_array(test,SIZE);

  for(int i=0;i<SIZE;i++)
  {
      printf("%c ,",test[i]);

  }

}

4 个答案:

答案 0 :(得分:1)

问题是您的函数数据类型,您无需将其定义为unsigned char *arr[]

此处为更正版本:

void sort_array(unsigned char *arr,int n)
{
    unsigned char tmp;
    for (int i=0;i<n-1;i++)
    {
         for(int j=i+1;j<n;j++)
         {
             if(arr[j]>arr[i])
             {
                tmp=arr[i];
                arr[i]=arr[j];
                arr[j]=tmp;
             }
         }
    }
}

答案 1 :(得分:1)

似乎您正在尝试对一维数组进行排序 您声明的变量“ unsigned char * arr []”表示它是一个指向阵列的POINTER。

在这种情况下,它也可以表示2D数组。

您可能想要使用unsigned char * arr,它表示一个指向char的指针。 在这种情况下,您可以像使用普通数组一样使用arr [i]来访问它!哇

答案 2 :(得分:0)

以上答案似乎可以解决您的问题。

对于打印排序的char数组,我建议使用%d而不是%c输出值,这样您就可以看到排序的结果。

for(int i=0;i<SIZE;i++)
{
    printf("%d ,", test[i]);
}

您会注意到,您的函数对数组进行了反向排序。 如果希望将数组按升序排序,请使用以下sort_array()

void sort_array(unsigned char *arr,int n)
{
    unsigned char tmp;
    for (int i=0;i<n-1;i++)
    {
         for(int j=i+1;j<n;j++)
         {
             if(arr[j]<arr[i])
             {
                tmp=arr[i];
                arr[i]=arr[j];
                arr[j]=tmp;
             }
         }
    }
}

唯一更改的地方是>行中的<符号(变为if(arr[j]<arr[i])符号)。

答案 3 :(得分:0)

clang编译器在编译代码时发出以下警告消息(用于编译的编译器必须发出类似的警告消息)

prg.c:28:14: warning: incompatible pointer types passing 'unsigned char [40]' 

to parameter of type 'unsigned char **' [-Wincompatible-pointer-types]
  sort_array(test,SIZE);
             ^~~~
prg.c:4:32: note: passing argument to parameter 'arr' here
void sort_array(unsigned char *arr[],int n)
                               ^
1 warning generated.

一个建议-不要忽略警告,它们出于某种原因而存在。

警告消息,指示test的类型与sort_array()参数arr的类型不兼容。 test的类型为unsigned char [SIZE],而arr的类型为unsigned char指针的数组。

您要在test中对数组sort_array()进行排序。有两种方法可以实现此目的:

  1. 将指针传递给数组test的第一个元素 sort_array()
  2. test数组指针传递到sort_array()

指向数组的第一个元素的指针和指向数组的指针的区别通常会使程序员感到困惑。

让我们讨论第一种方法-将指向数组test的第一个元素的指针传递给sort_array()
当您这样做

sort_array(test,SIZE);

这意味着您将指向数组第一个元素的指针传递给sort_array(),因为

&test[0] -> &(*(test + 0)) -> &(*(test)) -> &(*test) -> test

test数组的元素类型为unsigned char,因此arr的{​​{1}}参数的类型应为sort_array()。在这种情况下,unsigned char *原型应为:

sort_array()

void sort_array(unsigned char *arr, int n); 中,您可以像这样访问数组的元素-sort_array(),其中a[i]代表数组{{1的第i th 个元素}}。 i

test

请注意,在这种方法中,您需要传递要排序的数组大小。但这也提供了灵活性,您可以使用sort_array()对类型为void sort_array(unsigned char *arr, int n) { unsigned char tmp; for (int i = 0; i < n-1; i++) { for(int j = i + 1; j < n; j++) { if(arr[j] > arr[i]) { tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } } 的不同大小的数组进行排序。

现在是第二种方法-将sort_array()数组指针传递给unsigned char []

test的类型为sort_array(),因此其类型的指针为test。这意味着当您像这样将指向unsigned char [SIZE]数组的指针传递给unsigned char (*) [SIZE]

test

sort_array()原型的sort_array(&test); 参数的类型应为:

arr

请注意,在这种情况下,您不需要将数组大小传递给sort_array(),因为指针知道它可以指向的数组大小。

这样做的时候

void sort_array(unsigned char (*arr) [SIZE]);

您将获得

sort_array()

sizeof (*arr); 中,您可以像这样访问40 // because the SIZE is 40 数组的元素-sort_array(),其中test代表数组的第i th 元素(*arr)[i]。使用这种方法时,您可以执行以下操作:

i

输出:

test

请注意,在打印排序后的数组时,我使用的是#include <stdio.h> #define SIZE 40 void sort_array(unsigned char (*arr)[SIZE]) { unsigned char tmp; for (int i = 0; i < SIZE; i++) { for(int j = i + 1; j < SIZE; j++) { if((*arr)[j] > (*arr)[i]) { tmp = (*arr)[i]; (*arr)[i] = (*arr)[j]; (*arr)[j] = tmp; } } } } int main(void) { unsigned char test[SIZE] = { 34, 201, 190, 154, 8, 194, 2, 6, 114, 88, 45, 76, 123, 87, 25, 23, 200, 122, 150, 90, 92, 87, 177, 244, 201, 6, 12, 60, 8, 2, 5, 67, 7, 87, 250, 230, 99, 3, 100, 90}; sort_array(&test); for(int i = 0; i < SIZE; i++) { printf("%u", test[i]); (i+1) != SIZE ? printf(" ,") : printf("\n"); } return 0; } 格式说明符。当您使用250 ,244 ,230 ,201 ,201 ,200 ,194 ,190 ,177 ,154 ,150 ,123 ,122 ,114 ,100 ,99 ,92 ,90 ,90 ,88 ,87 ,87 ,87 ,76 ,67 ,60 ,45 ,34 ,25 ,23 ,12 ,8 ,8 ,7 ,6 ,6 ,5 ,3 ,2 ,2 打印ASCII字符时,%u将打印与十进制值%c对应的ASCII字符,但请记住,从printf()test[i]的ASCII字符是不可打印的字符,并且您的0数组的值在此范围内。

使用指针指向数组方法的局限性在于,31的{​​{1}}参数将期望使用test类型的数组的地址。如果您传递的是arr以外的其他大小的sort_array()数组的地址,则编译器将引发警告消息。

当然,在您的情况下,指向数组方法的第一个元素的指针似乎更合适,但是很高兴知道这些概念。