将"char (*)[3]"传递给类型为"const char * "的参数的不兼容指针类型



使用以下代码:

char randnum[KEYSIZE + 1];
char temp[3];
char buff[KEYSIZE*2 + 1] = {0};  
for (j = 0; i < KEYSIZE; i++) {
randnum[i]  = rand()%256;

snprintf(temp, 3, "%.2x", (unsigned char)randnum[i]);
strcat(buff, &temp);
}

我在&temp拿到incompatible pointer types passing 'char (*)[3]' to parameter of type 'const char *。这是通过使用temp来修复的。

我正在努力理解错误信息。我理解const char *是一个指针,但我不确定char (*)[3]指的是什么;特别是CCD_ 6。根据我从修复中推断出的内容,我假设这是一个指向指针的指针(EDIT:pointer)。这是正确的吗?

&temp整个数组的地址。该数组的类型为char [3],因此地址(指针)的类型是指向该数组的指针,表示为char (*) [3],将其读取为"0";指向3个chars的阵列的指针";。

我假设这是一个指向指针的指针

不,它是指向数组的指针。

&temp是指向数组本身的指针,它确实具有类型char (*)[3](它是指向三个char元素的数组的指针)。

您应该将指针传递到字符串的第一个元素,即&temp[0],这就是普通temp衰减的结果。

因此:

strcat(buff, temp);

函数strcat以以下方式声明

char *strcat(char * restrict s1, const char * restrict s2);

正如您所看到的,它的两个参数都需要类型为char *const char *的表达式。

在函数的调用中

strcat(buff, &temp);

由于像一样声明的数组指示符buff的隐式转换,第一个自变量表达式确实具有类型char *

char buff[KEYSIZE*2 + 1] = {0};  

指向指向其第一个元素的指针。

而第二个参数表达式的类型为char ( * )[3],因为您将运算符&的地址用于数组temp

&temp

您还需要使用数组指示符temp作为参数。在这种情况下,它将以与数组buff类似的方式隐式转换为指向其第一个元素的指针。

strcat(buff, temp);

请注意,最初应该将数组random声明为具有元素类型unsigned char

unsigned char randnum[KEYSIZE + 1];

此外,由于数组没有被设计为包含字符串,因此它也可以像一样被声明

unsigned char randnum[KEYSIZE];

char randnum[KEYSIZE+1];

数组衰减为指针。

char temp[3];
  • temp衰减为指向引用数组第一个元素的字符的指针(char *)
  • &temp衰减为指向引用数组开头的3个字符数组(char (*)[3])的指针
  • &temp[n]衰减为指向引用数组第n个元素的字符的指针(char *)

strcat函数声明为(C17 7.24.3.1):

char *strcat(char * restrict s1,
const char * restrict s2);

对于本讨论而言,重要的部分是函数对两个参数都期望char*。尽管我们可以注意到char*可以分配给const char*,但不能反过来。

如果我们看看正确的用法strcat(buff, temp);,那么该表达式中的bufftemp都是数组。但在大多数情况下,当在表达式中使用数组时;衰变";在这种情况下,它变为char*

正式地说;衰变;定义为(C17 6.3.2.1):

除非它是sizeof运算符、一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为">类型的数组"的表达式将转换为类型为"指向型型"的表达式,该表达式指向数组对象的初始元素,而不是左值。

然而当您键入&temp时,您会偶然发现上面提到的"异常之一;阵列衰减";规则,即当与一元&一起使用时。

因此,我们最终得到的不是CCD_ 46;CCD_ 47"的地址;。它必须用指向数组时使用的特殊指针类型char (*)[3]来表示,称为";指向数组的指针";或";数组指针";。

C对隐式指针转换有非常严格的规则——它不会接受将char(*)[3]传递给预期为const char*的参数——它们是不兼容的指针类型——这不是一种有效的赋值形式。

当您知道所有这些之后,编译器错误实际上是不言自明的。

char (*)[3]是指向大小为3的数组的指针。

CCD_;天然的";形式为CCD_ 53型。然而,因为temp也指向数组的第一个元素(它是char),所以允许"0";衰变;转换为CCD_ 56。

当您取&temp时,它给出了temp变量的地址,而不是地址位于数组中。再次,在其最";天然的";形式,&temp(*)0类型,因为它是指向char[3]的指针。但是,请注意,它不再是数组类型(而是指向数组的指针),因此不允许衰减为char**

strcat(buff, temp);修复了这个问题,因为strcat想要的是char*,而不是char (*)[3]

最新更新