指向数组的typedef的指针

时间:2017-12-29 14:15:13

标签: c arrays pointers types typedef

我试图做以下事情:

#include <stdio.h>

typedef unsigned char Set[128];

Set A;  //Global variable

void main()
{
    A[0] = 1;
    A[1] = 2;
    A[2] = 3;
    printf("%x, %x, %x\n", A, &A, &A[0]);
    printf("%u, %u, %u\n", A[0], A[1], A[2]);
    Set *p;
    p = A;  //Same result with:  p = &A;
    printf("%x, %x, %x\n", p, &p, &p[0]);
    printf("%u, %u, %u\n", p[0], p[1], p[2]);
}

第一次和第三次打印都很好 - 我可以看到这两个变量的地址,并且对于&#39; p&#39;它所指的地址。 我想要&#39; p&#39;指出&#39; A&#39;所以我能够访问&#39; A&#39;的数组中的值。通过&#39; p&#39;,但它不起作用 - 第四次打印的值不是第二次打印,它不打印数组的值。 如何创建指向“设置”的指针?变量型?

3 个答案:

答案 0 :(得分:2)

您为所提供的参数类型使用了许多错误/不匹配的格式说明符。这会导致undefined behavior

请记住,对于指针类型,必须使用%p格式说明符,如果指针不是指向char类型的指针,则必须将参数强制转换为void *

关于上述演员要求的陈述,请参阅章节6.2.5 / P28,

  

指向void的指针应具有与a相同的表示和对齐要求   指向字符类型的指针。 [....]

和脚注48,

  

相同的表示和对齐要求意味着可互换性   函数的参数,函数的返回值以及联合的成员。

话虽如此,总是要注意类型!!

在您的代码中,

  • A的类型为unsigned char [128](数组),
  • p的类型为unsigned char (*) [128]

因此,p = A;不是有效语句,因为类型不兼容。您必须使用A的地址才能使该语句有效,例如

 p = &A;  // now the types are compatible

答案 1 :(得分:1)

那是因为p的指针类型与a的类型不同。在您尝试使用p[1]时,您基本上尝试访问一些您无法访问的内存。 (当您访问p[1]等时,您有未定义的行为)。而且由于类型不匹配,您还会在printf本身遇到未定义的行为。

相反,你可以得到你想要的东西(现在你将获得所需的数组元素)。

printf("%u, %u, %u\n", (*p)[0], (*p)[1], (*p)[2]);

同样要输入ponters,请使用%p格式说明符。 (将其投射到void*)。

printf("%p, %p, %p\n", (void*)A, (void*)&A, (void*)&A[0]);

如何编译代码?

还尝试在启用所有警告的情况下编译代码。 gcc -Wall -Werror progname.c

编译器抱怨了!

p=A编译器也抱怨它。因为您要将unsigned char*分配给unsigned char(*)[128]

 error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
     p = A;  //Same result with:  p = &A;
       ^

error: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘unsigned char (*)[128]’ [-Werror=format=]
     printf("%x, %x, %x\n", p, &p, &p[0]);
                      ^

如何使这些警告消失?

p=&A;

这将执行正确的分配。并使用正确的格式说明符,如答案中所述。

unsigned char*是如何出现的?

在这种情况下,井阵列衰减成指针 - 它衰变成指向第一个元素的指针。第一个元素的类型是unsigned char - 指向它的指针是unsigned char*。这就是它如何产生......

答案 2 :(得分:1)

p是指向unsigned char [128]类型的指针,表示其类型为unsigned char (*)[128],而A的类型在衰减后为unsigned char *。两者都是不兼容的类型。你需要

p = &A; 

printf("%p, %p, %p\n", (void *)A, (void *)&A, (void *)&A[0]);
printf("%u, %u, %u\n", A[0], A[1], A[2]);
Set *p;
p = &A; // Assign address of A which is of type unsigned char (*)[128]
printf("%p, %p, %p\n", (void *)p[0], (void *)p, (void *)&p[0]);
printf("%u, %u, %u\n", p[0][0], p[0][1], p[0][2]);