指向数组的typedef的指针

问题描述 投票:0回答:3

我正在尝试做以下事情:

#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'数组中的值,但它不起作用 - 第四次打印时的值不是第二,它不打印数组的值。如何创建指向“设置”变量类型的指针?

c arrays pointers types typedef
3个回答
2
投票

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

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


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

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

和脚注48,

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


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

在你的代码中,

  • A的类型为unsigned char [128](array),
  • punsigned char (*) [128]类型。

因此,p = A;不是有效的声明,因为类型不兼容。你必须使用A的地址使声明有效,类似于

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

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

How to compile code?

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

Compiler complained!

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]);
                      ^

How to make these warnings go away?

p=&A;

这将做正确的任务。并使用正确的格式说明符,如答案中所述。

How did the unsigned char* appear?

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


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]);
© www.soinside.com 2019 - 2024. All rights reserved.