为指针分配整数时,为什么使用强制转换更好?

时间:2014-07-29 14:55:49

标签: c pointers casting

我们假设我有这段代码:

  char *pointer;
  unsigned int a;
  pointer = a;

对我而言,这不会产生任何问题,但我会收到以下警告:

assignment makes pointer from integer without a cast

为什么使用演员会更好? 我使用的是32位机器。

编辑: 通过"这不会产生任何问题",我说它编译并指针存储变量a的值。

编辑: 变量a实际上会存储一个地址。

4 个答案:

答案 0 :(得分:10)

最好不要尝试在所有的指针上分配一个整数值。在极少数情况下,这样的任务是有意义的,演员阵容不仅仅是更好,而且是必需的。

指针和整数是不同的类型。在某些情况下,混合它们是有意义的;在这种情况下,你需要一个强制转换,因为整数和指针之间没有隐式转换(除了0的特殊情况,被视为空指针常量)。

char *pointer;
int a;         /* or unsigned int a, it's the same either way */
pointer = a;

此分配是非法的(更确切地说,约束违规)。符合标准的C编译器必须至少警告它。许多编译器在打印警告后,将生成执行隐式转换的代码,但语言不需要这些代码,您不应该依赖它。我个人认为,这样做的编译器并没有给你带来任何好处。

pointer = (char*)a;

这是合法的;演员告诉编译器生成从intchar*的转换。但是,转换的结果是实现定义的,很可能不会产生有意义的结果 - 即使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

等等......

但是,你一直记得的是指针不仅是一个内存地址。它是内存地址类型的组合。