C:检查数组是否包含相等的连续元素

C:检查数组是否包含相等的连续元素,c,arrays,type-conversion,c-strings,void-pointers,C,Arrays,Type Conversion,C Strings,Void Pointers,昨天我在C上做了一个测试,我想不出最后一个问题: 我们得到了两种类型的数组:包含相等的连续元素的数组(例如:{“stack”、“heap”、“heap”})和没有相等的连续元素的数组(例如:{1,2,3,4,5,6,7,8,9}) 然后,我们被要求找到一个函数,如果给定的数组包含或不包含double,则该函数返回1或0。所以这个函数必须同时处理整数数组和char*数组 这就是我今天想到的(但它总是给出错误的答案,然后崩溃,或者在比较字符串时出现分段错误) 编辑:正确的代码(感谢@BLUEPIXY

昨天我在C上做了一个测试,我想不出最后一个问题:

我们得到了两种类型的数组:包含相等的连续元素的数组(例如:{“stack”、“heap”、“heap”})和没有相等的连续元素的数组(例如:{1,2,3,4,5,6,7,8,9})

然后,我们被要求找到一个函数,如果给定的数组包含或不包含double,则该函数返回1或0。所以这个函数必须同时处理整数数组和char*数组

这就是我今天想到的(但它总是给出错误的答案,然后崩溃,或者在比较字符串时出现分段错误)

编辑:正确的代码(感谢@BLUEPIXY!)

#包括
#包括
#包括
int包含_dup(void*数组,size\t size,size\t sizeoftype,int(*cmp)(常量void*,常量void*)){
//数组!=NULL,大小!=0
char*obj=数组;
尺寸i;
对于(i=0;i
错误的旧代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int array_contains_doubles(void ** array, int size, int sizeoftype){
 int i;
 char **out =(char**) malloc(size * sizeof(char*));

 for(i=0;i<size;i++){            //trying to convert the array of ints to an 
    out[i] = array+i*sizeoftype; //array of char * eg: {1,2} ->{"1","2"}
//  *out[i] +='a';
    printf("%c\n",*out[i]);

 }
 out[i]= NULL;

 while(*(out+1)!=NULL){ 
    if(strcmp(*out,*(out++))==0){ //<- where i get the segmentation error
            return 1;
    }

 }

 return 0;

 }


int main(void){
  int i;
  int ints_yes[] = {0,1,2,2,2,3,4,4,5};
  int ints_no[]={0,1,2,3,4,5,6,7,8};
  char * strings_yes[]={"heap","stack","stack","overflow"};
  char * strings_no[]={"heap","stack","heap","stack","overflow"};

  int test = array_contains_doubles((void **) ints_no, 
  sizeof(ints_no)/sizeof(ints_no[0]), sizeof(int));

  (test) ? (printf("doubles? Yes")) : (printf("doubles? No"));

}
#包括
#包括
#包括
int-array\u包含双精度(void**array,int-size,int-sizeoftype){
int i;
char**out=(char**)malloc(size*sizeof(char*);
对于(i=0;i{“1”,“2”}
//*输出[i]+='a';
printf(“%c\n”,*out[i]);
}
out[i]=NULL;
while(*(out+1)!=NULL){

如果(strcmp(*out,*(out++)==0){/您的老师可能正在寻找的是您实现一个类似于传递给
bsearch
的函数指针的“functor”(研究此函数)。大致如下:

typedef int comp_func_t (const void*, const void*);

bool equal (const void* obj1, const void* obj2, comp_func_t* comp)
{
  return comp(obj1, obj2)==0;
}
您可以从应用程序中调用
equal
,并使用指向要比较的对象的指针,而不管它们是什么类型的对象。函数指针指定应如何比较这种类型的对象。然后为每种类型实现比较函数:

int comp_int (const void* obj1, const void* obj2)
{
  int a = *(const int*)obj1;
  int b = *(const int*)obj2;

  if(a < b)
  {
    return -1;
  }
  else if(a > b)
  {
    return 1;
  }
  else // a == b
  {
    return 0;
  }
}

int comp_str (const void* obj1, const void* obj2)
{
  ...
}
现在,它只比较两个对象,因此您必须对数组进行扩展,方法是1)对数组进行排序,2)对排序数组中的每两个相邻项调用它,以确定是否有相等的项


以上是旧的“事实标准”在C语言的较新版本中,可以通过
\u Generic
关键字获得更优雅的方法,但这可能不会在初学者级别的类中解决。

您将数组与指针混淆。
数组包含\u double
需要指向
void*
的指针,但是
ints\u no
自动转换为
&ints\u no[0]
,它是指向
int
的指针。
(void**)
cast隐藏错误。
ints\u no
不是双指针。我建议将
array\u contains\u doubles
更改为使用
void*
参数而不是
void**
参数,因为
void*
可以指向任何对象,无论其类型如何。要比较两个对象,需要知道它们的类型和执行类型适当的比较。单个函数对多个不同类型执行此操作的唯一方法是,向其传递一个参数,该参数允许它确定要执行的比较类型。标准函数是此类操作的典型示例--请注意,它的一个参数是指向类型适当的comp的指针arison函数。是不是
if(strcmp(*out,*(out++)==0)
UB?我想你应该用
if(strcmp(*out,*(out+1))==0)替换它。
谢谢,我想是这样的,但最后我不敢写一个单独的函数,因为问题只使用了一个函数(我可能误解了这一点,事后看来,它们可能只是意味着我们无法编写两个函数“int-check\u-array\u of-int”和“int-check\u-array\u of-u-strings”)。在这种情况下,数组应该不排序,因为问题是检查连续的重复,而不是任何重复。
int comp_int (const void* obj1, const void* obj2)
{
  int a = *(const int*)obj1;
  int b = *(const int*)obj2;

  if(a < b)
  {
    return -1;
  }
  else if(a > b)
  {
    return 1;
  }
  else // a == b
  {
    return 0;
  }
}

int comp_str (const void* obj1, const void* obj2)
{
  ...
}
int x;
int y;
...
if(equal(&x, &y, comp_int))
{
  ...
}