我正在尝试做以下事情:
#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]);
}
第一次和第三次打印都很好 - 我可以看到两个变量的地址,而'p'指的是地址。我想'p'指向'A'所以我将能够访问'A'到'p'数组中的值,但它不起作用 - 第四次打印时的值不是第二,它不打印数组的值。如何创建指向“设置”变量类型的指针?
您为所提供的参数类型使用了许多错误/不匹配的格式说明符。这导致undefined behavior。
请记住,对于指针类型,必须使用%p
格式说明符,如果指针不是指向char
类型的指针,则必须将参数强制转换为void *
。
关于上述演员要求的陈述,请参阅§6.2.5/ P28章节,
指向void的指针应具有与指向字符类型的指针相同的表示和对齐要求。 [....]
和脚注48,
相同的表示和对齐要求意味着可互换性作为函数的参数,函数的返回值和联合的成员。
话虽如此,总是注意类型!!
在你的代码中,
A
的类型为unsigned char [128]
(array),p
是unsigned char (*) [128]
类型。因此,p = A;
不是有效的声明,因为类型不兼容。你必须使用A
的地址使声明有效,类似于
p = &A; // now the types are compatible
那是因为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*
appear?在这种情况下,井阵列衰减成指针 - 它衰变成指向第一个元素的指针。第一个元素的类型是unsigned char
- 指向它的指针是unsigned char*
。这就是它如何形成......
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]);