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