简体   繁体   English

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

[英]incompatible pointer types passing 'char (*)[3]' to parameter of type 'const char *

With the following code:使用以下代码:

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);
}

I'm getting incompatible pointer types passing 'char (*)[3]' to parameter of type 'const char * at &temp .我得到了incompatible pointer types passing 'char (*)[3]' to parameter of type 'const char * at &temp This is fixed by using temp instead.这是通过使用temp来解决的。

I'm trying to understand the error message.我正在尝试理解错误消息。 I understand const char * to be a pointer but I'm not sure what char (*)[3] is referring to;我理解const char *是一个指针,但我不确定char (*)[3]指的是什么; specifically the (*) .特别是(*) From what I can infer from the fix, I assume this to be a pointer to a pointer (EDIT: pointer).从我可以从修复中推断出来,我假设这是一个指向指针的指针(编辑:指针)。 Is this correct?这样对吗?

&temp is the address of the whole array . &temp整个数组的地址。 The array is of type char [3] , so the type of the address (pointer) is a pointer to that array, which is expressed as char (*) [3] , read it as "pointer to an array of 3 char s".数组的类型是char [3] ,因此地址(指针)的类型是指向该数组的指针,表示为char (*) [3] ,读作“指向 3 个char的数组的指针” ”。

I assume this to be a pointer to a pointer.我假设这是一个指向指针的指针。

No, it's pointer to an array.不,它是指向数组的指针。

&temp is a pointer to the array itself, and it does indeed have the type char (*)[3] (it's a pointer to an array of three char elements). &temp是一个指向数组本身的指针,它确实具有char (*)[3] (它是一个指向由三个char元素组成的数组的指针)。

You should pass a pointer to the first element of the string, ie &temp[0] , which is what plain temp decay to.您应该传递一个指向字符串第一个元素的指针,即&temp[0] ,这是普通temp衰减到的。

So:所以:

strcat(buff, temp);

The function strcat is declared the following way函数strcat声明如下

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

As you can see the both its parameters expect expressions of the type char * or const char * .正如您所看到的,它的两个参数都期望char *const char *类型的表达式。

In this call of the function在这个函数调用中

strcat(buff, &temp);

The first argument expression is indeed has the type char * due to the implicit conversion of the array designator buff declared like由于声明为数组指示符buff的隐式转换,第一个参数表达式确实具有char *类型

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

to a pointer to its first element.指向其第一个元素的指针。

While the second argument expression has the type char ( * )[3] because you used the address of operator & for the array temp虽然第二个参数表达式的类型为char ( * )[3]因为您将运算符&的地址用于数组temp

&temp

You need also to use as the argument the array designator temp .您还需要使用数组指示符temp作为参数。 In this case it will be implicitly converted to a pointer to its first element the similar way as with the array buff .在这种情况下,它将以与数组buff类似的方式隐式转换为指向其第一个元素的指针。

strcat(buff, temp);

Pay attention to that initially the array random should be declared as having the element type unsigned char .请注意,最初应将数组random声明为元素类型unsigned char

unsigned char randnum[KEYSIZE + 1];

Moreover as the array is not designed to contain a string then it may be declared also like此外,由于数组不是设计为包含字符串,因此它也可以像这样声明

unsigned char randnum[KEYSIZE];

char randnum[KEYSIZE + 1];字符随机数[KEYSIZE + 1];

Arrays decay to pointers.数组衰减为指针。

char temp[3];
  • temp decays to pointer to char ( char * ) referring the first element of the array temp衰减到指向 char ( char * ) 的指针,指的是数组的第一个元素
  • &temp decays to pointer to array of 3 characters ( char (*)[3] ) referring beginning of the array &temp衰减到指向数组开头的 3 个字符( char (*)[3] )的指针
  • &temp[n] decays to pointer to char ( char * ) referring the n-th element of the array &temp[n]衰减到指向 char ( char * ) 的指针,指向数组的第 n 个元素

The strcat function is declared as (C17 7.24.3.1): strcat函数声明为 (C17 7.24.3.1):

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

Where the important part for the sake of this discussion is that the function expects char* for both parameters.对于本次讨论而言,重要的部分是该函数对两个参数都需要char* Though we can note that a char* can be assigned to a const char* , but not the other way around.虽然我们可以注意到char*可以分配给const char* ,但const char*不行。

If we look at the correct use, strcat(buff, temp);如果我们看一下正确的用法, strcat(buff, temp); , then both buff and temp in that expression are arrays. ,那么该表达式中的bufftemp都是数组。 But in most cases when an array is used in an expression, it "decays" into a pointer to it's first element, it becomes a char* in this case.但是在大多数情况下,当在表达式中使用数组时,它会“衰减”为指向其第一个元素的指针,在这种情况下它变为char*

Formally this "decay" is defined as (C17 6.3.2.1):这种“衰减”正式定义为 (C17 6.3.2.1):

Except when it is the operand of the sizeof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type '' is converted to an expression with type ''pointer to type '' that points to the initial element of the array object and is not an lvalue.除非它是sizeof运算符的操作数,或者一元&运算符,或者是用于初始化数组的字符串文字,否则类型为 ''array of type '' 的表达式将转换为类型为 ''pointer 的表达式键入'' 指向数组对象的初始元素并且不是左值。

However when you type &temp , you stumble upon one of the above mentioned exceptions to this "array decay" rule, namely when used with the unary & .但是,当您键入&temp ,您会偶然发现上述“数组衰减”规则的例外之一,即与一元&

So instead of a char* we end up with "address of a char [3] ".因此,我们最终得到的不是char*而是“ char [3]地址”。 Which has to be expressed with a special pointer type used when pointing at arrays, char (*)[3] , known as "pointer to array" or "array pointer".它必须用指向数组时使用的特殊指针类型表示, char (*)[3] ,称为“指向数组的指针”或“数组指针”。

C has pretty strict rules regarding implicit pointer conversions - it will not accept that a char(*)[3] is passed to a parameter expected to be const char* - they are incompatible pointer types - it is not a valid form of assignment. C 对隐式指针转换有非常严格的规则——它不会接受将char(*)[3]传递给预期为const char*的参数——它们是不兼容的指针类型——它不是一种有效的赋值形式。

When you know all of this, the compiler error is actually quite self-explanatory.当您了解所有这些后,编译器错误实际上是不言自明的。

char (*)[3] is a pointer to an array of size 3. char (*)[3]是一个指向大小为 3 的数组的指针。

temp in its most "natural" form is of type char[3] . temp最“自然”的形式是char[3]类型。 However, because temp also points to the first element of the array (which is a char ), it is allowed to "decay" into a char* .然而,因为temp也指向数组的第一个元素(它是一个char ),它被允许“衰减”成一个char*

When you take &temp , that gives the address of the temp variable, not an address is located in the array.当你使用&temp ,它给出了temp变量的地址,而不是位于数组中的地址。 Again, in its most "natural" form, &temp is of type char (*)[3] because it is a pointer to a char[3] .同样,在其最“自然”的形式中, &tempchar (*)[3]因为它是指向char[3]的指针。 However, note that it is no longer an array type (rather a pointer-to-array), so it is not allowed to decay to char** .然而,请注意,它不再是一种阵列型(而一个指针到阵列),所以它是不允许的衰减到char**

strcat(buff, temp); fixes this because strcat wants a char* , not a char (*)[3] .解决这个问题是因为strcat想要一个char* ,而不是一个char (*)[3]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM