将指向int数组的指针传递给C函数

3

我有一个非常基础的问题。

这个调用有什么问题?

int params[2] = {1, 1};
return strcmp95((char*)buffer1, (char*)buffer2, (long)stringLength, &params);

函数定义如下:
double  strcmp95(char *ying, char *yang, long y_length, int *ind_c[])

{...

当我在XCode中编译时,我得到了以下警告:
警告:从不兼容的指针类型传递第4个参数'strcmp95'
抱歉表述不够精确。这是函数描述:
/* 参数: ying和yang是要比较的2个字符串的指针。这些字符串不需要是以NUL结尾的字符串,因为长度被传递。 y_length是字符串的长度。 ind_c是一个数组,用于定义是否应激活某些选项。非零值表示选项已停用。
选项包括: ind_c [0]:当匹配字符数很大时,增加匹配概率。此选项允许在字符串较大时有更多的容差。在比较固定长度字段(如电话号码和社会保障号码)时,它不是一个适当的测试。 ind_c [1]:在比较之前将所有小写字符转换为大写字符。禁用此功能意味着小写字符串“code”不会被认为与大写字符串“CODE”相同。此外,类似字符调整部分仅适用于大写字符。 对于像名称这样的字符字符串,建议所有值都为零。*/

你是说这在其他地方编译不了吗?也就是说这只是针对Xcode的问题? - deceleratedcaviar
我不知道,所以我添加了标签。可能是XCode中缺少了某些东西。 - Joseph Tura
5个回答

4

params 是一个 int [2] 数组,当传递给函数时将会转化为 int * 指针。那些以 int [] 作为参数的函数,在幕后实际上是使用 int * 操作的。不幸的是,&params 是一个 int(*)[2] 类型,这比你需要的 int ** (在函数参数中等同于 int *[]) 更接近 int *

你最好的选择是将你的函数修改为:

double  strcmp95(char *ying, char *yang, long y_length, int *ind_c)

假设调用者总是传递一个int[2]。或者你可以明确要求一个int(*)[2] - 一个指向包含2个int的数组的指针:

double  strcmp95(char *ying, char *yang, long y_length, int (*ind_c)[2])

但是为了保证传递两个int是不必要的,如果需要考虑数组中可能超过两个int的情况,则不适用。更好的方法是:

double  strcmp95(char *ying, char *yang, long y_length, int *ind_c, size_t len)

size_t是一个无符号整数类型,保证能够容纳任何对象或数组索引的大小,而在这种情况下,len参数是您的数组长度(如果您想要更加高级/前瞻性,则为(sizeof params / sizeof params[0]),如果您不需要,则为2)。这是最安全的方法。

顺便说一句,您的y_length参数也应该是一个size_t变量。 long是有符号的,我不想处理一个长度为-1的字符串。即使您使用unsigned long,也不能保证long足以处理系统的大小(或者相反,错误地使用了一个过大的long值会使您的系统难以处理并导致混乱)。


不,&paramsparams不同。它们所持有的地址相同,但是&params的类型为int (*)[2] - Jens Gustedt
我选择了int (*ind_c)[2]。这个函数只会被我自己调用,而且只在一个地方使用。这种情况下,这个选项似乎非常安全。 - Joseph Tura
@Jens - 当你说“我今晚早点睡觉,明天起个正常的时间”后熬夜到凌晨5点就会发生这种事情。正在修复中。 - Chris Lutz
@Joseph - 如果你只在一个地方调用它,并且有如此特定的数组要求,为什么它要是一个单独的函数呢? - Chris Lutz
这是一个1994年编写的函数,不是我自己写的。我只是在使用它。 :) - Joseph Tura
哇,当有人写下这段代码时,我才4岁。他们从未想过有个4岁的孩子会长大后用手机回答关于他们代码的问题。就我个人而言,我会将数组中的两个“int”值分别作为“int”参数,以便函数调用者不必声明临时数组来调用它。 - Chris Lutz

2

strcmp95 接受一个指向指针的指针 (int **),但是您正在传递一个指向包含两个整数的数组的指针 (int (*)[2])。

您可以修改 strcmp95 的签名,使其看起来像这样:

double  strcmp95(char *ying, char *yang, long y_length, int (*ind_c)[] );

这里的关键是指向数组的指针(int (*x)[])与指针数组并不相同(指针数组是 int *(x[]),与 int *x[] 相同)


嗯...好的。我会尝试弄清楚如何进行更改。:) 这两种方法各有什么优缺点? - Joseph Tura
@Joseph Tura:我更新了答案。int *x[]是一个指针数组,而你正在传递一个数组的指针。 - peoro

1

为什么要传递 &params,params 本身作为一个数组就像一个指针。

return strcmp95((char*)buffer1, (char*)buffer2, (long)stringLength, params);

其次,strcmp95现在应该期望一个整数数组,这将是没问题的:

double  strcmp95(char *ying, char *yang, long y_length, int ind_c[])

1
很难确定strcmp95函数是否应该取一个整数数组,就像你试图传递的那样,还是它应该取一个整数指针数组作为原型请求。前者似乎更有可能-如果是这样,您应该更改...
double  strcmp95(char *ying, char *yang, long y_length, int *ind_c[])

...到...

double  strcmp95(char *ying, char *yang, long y_length, int *ind_c)

...或者等价地...

double  strcmp95(char *ying, char *yang, long y_length, int ind_c[])

1

我认为您正在传递参数(本身是整数指针),而函数strncmp95期望的是指向整数数组的指针,即int *ind_c[]。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接