0

我认为在将值分配给指针时,您应该使用 * 运算符,但我看到了类似的代码

char *a;
void *b;
b = "Hello";
a = b;
printf("%s", a);

当我编译它并打印 Hello 时这是合法的。不需要指向无效解除引用的指针吗?

4

4 回答 4

4

这“有效”是因为 avoid *和 achar *能够保存任何类型的指针。您可能会遇到麻烦,例如,如果您使用int *a;而不是void *a;.

但是,您的代码没有取消引用void指针,并且 printf 函数char *在将参数从列表中的变量参数中拉出时将其转换为 a 。因此,您的代码中没有取消引用 void 指针。如果您的指针在某些类型的机器上没有完美地转换为 a char *(例如,如果我们有一个int *a;),这些机器在没有“额外信息”的情况下不寻址字节(有些机器只有“指针”指向整个机器字和额外信息用于在读取字节时存储您想要的那个字中的哪个字节),那么您的 printf 很可能无法正确操作 [“未定义的行为”]。

于 2013-01-24T15:39:42.310 回答
1

C 中没有字符串类型。您可以将char*指向char数组开头的指针视为字符串。这正是这里的printf待遇a

据我记得,C 标准要求char*并且void*可以互换。

于 2013-01-24T15:32:12.800 回答
1

指向 void 的指针不需要取消引用,事实上,取消引用 void 指针是非法的。您显然可以将任何指针转换为 void 指针,并将 void 指针转换为任何其他指针类型。

这就是为什么:

void *b = "hello world";工作,所以做了char *a = b,然后打印a出来。这里发生的是:

char *a; // declares a as a pointer to char
void *b; // declares b as a void pointer(which can hold an address)
b = "Hello"; // 'b' now holds the address, that points to the start of "Hello"
a = b; // now, 'a' contains the address that 'b' does
printf("%s", a); // prints the string, starting from the address pointed by 'a'.

因此这是完全合法的。

于 2013-01-24T15:37:44.410 回答
0

b = "Hello"; 这一行分配了一堆 char 内存并将其地址分配给void指针变量b

void 指针可以存储任何其他数据类型的地址。void 指针的唯一限制是:

  • 由于显而易见的原因,无法取消引用 void 指针
  • sizeof(void)是非法的
  • 您不能对 void 指针执行指针运算

但是 GCC 假定它sizeof(void)是 1 并允许对 void 指针进行指针算术。

a=b;这是典型的 char 指针a,初始化为包含在 void 指针中的地址b。这是合法的,但如果滥用可能会产生影响。

printf("%s", a);这是一个简单的 printf 语句。

这段代码中的一切都很好。

是的,您需要使用*指针为分配的内存分配一个值:例如:

   char *c=malloc(sizeof(char));
   *c='a';

或者

   char a='a';
   char *c=&a;
   *c='b';

此外,在使用双指针时,您将使用*来初始化另一个指针。

   char *a=NULL;
   mymalloc(&a);


   void mymalloc(char **a)
   {
     *a=malloc(10);
     return;
   }

希望这可以帮助。

于 2013-01-24T15:31:38.387 回答