我们假设我有这段代码:
char *pointer;
unsigned int a;
pointer = a;
对我而言,这不会产生任何问题,但我会收到以下警告:
assignment makes pointer from integer without a cast
为什么使用演员会更好? 我使用的是32位机器。
编辑:
通过"这不会产生任何问题",我说它编译并指针存储变量a
的值。
编辑:
变量a
实际上会存储一个地址。
答案 0 :(得分:10)
最好不要尝试在所有的指针上分配一个整数值。在极少数情况下,这样的任务是有意义的,演员阵容不仅仅是更好,而且是必需的。
指针和整数是不同的类型。在某些情况下,混合它们是有意义的;在这种情况下,你需要一个强制转换,因为整数和指针之间没有隐式转换(除了0
的特殊情况,被视为空指针常量)。
char *pointer;
int a; /* or unsigned int a, it's the same either way */
pointer = a;
此分配是非法的(更确切地说,约束违规)。符合标准的C编译器必须至少警告它。许多编译器在打印警告后,将生成执行隐式转换的代码,但语言不需要这些代码,您不应该依赖它。我个人认为,这样做的编译器并没有给你带来任何好处。
pointer = (char*)a;
这是合法的;演员告诉编译器生成从int
到char*
的转换。但是,转换的结果是实现定义的,很可能不会产生有意义的结果 - 即使char*
和int
碰巧大小相同。
(在您的问题中的代码中,a
尚未初始化。我认为在您未向我们展示的实际代码中并非如此。)
你到底想要完成什么?
答案 1 :(得分:6)
因为在C:
pointer = a; // not valid in C: a is an int object
// pointer an object of pointer type
该语句无效,您需要显式转换(强制转换)以将a
值转换为指针类型。
pointer = (char *) a; // valid assignmnent
有些编译器对你很好,并且会隐式地将int
值转换为指针类型(并添加警告!)但是它们不是必须这样做的,并且编译器可以拒绝编译你的程序。 / p>
答案 2 :(得分:3)
% cat int-cast.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("sizeof char *: %zu\n", sizeof (char *));
printf("sizeof int: %zu\n", sizeof (int));
}
然后,如果编译32或64位类型的大小不同
% cc -m32 int-cast.c && ./a.out
sizeof char *: 4
sizeof int: 4
% cc -m64 int-cast.c && ./a.out
sizeof char *: 8
sizeof int: 4
正如Keith Thompson明确指出的那样,即使它们保证大小相同,仍然需要强制转换,结果最好是实现定义的。
答案 3 :(得分:0)
在C中,指针不仅是内存中的地址,它还是一个类型:
pointer = memory size + type
理解这一点的最好方法是考虑指针运算,以防止做一些算术运算。例如,你可以这样做:
int i;
int * ptr, ptr2;
ptr = &i; // Assign the address of an int to an int pointer
ptr2 = ptr + 2; // Shift the pointer of two int size further
i = ptr - ptr2; // Compute the number of slots between ptr and ptr2
但是,你做不到:
int i;
char c;
int * ptr;
char * ptr2;
ptr = &c; // The types are not matching, the compiler will complain
ptr = 2 * ptr; // This is not allowed by pointer arithmetic
ptr = ptr + ptr; // This is not allowed by pointer arithmetic
等等......
但是,你一直记得的是指针不仅是一个内存地址。它是内存地址和类型的组合。