C指针语法

时间:2011-12-23 10:09:21

标签: c pointers syntax

这两行代码之间有什么区别?

int *ptr = &x;

void* q = &x;
int* p = q;

我对C和指针的概念非常陌生 - 主要是用Java教过 - 所以只是有点困惑。

提前致谢。

4 个答案:

答案 0 :(得分:4)

void *用于记录C.中的通用指针 意思是它可以指向任何类型。

因此,在第一种情况int *ptr = &x;中,您使用指向int的指针,因此使用它的任何人都知道它正在操纵整数。

在第二种情况void* q = &x;中,您通过gereric指针指向整数地址 问题是不清楚这个指针指的是什么类型。

因此,第一个和第二个示例具有相同的效果(在您的具体示例中),但void *不能像这样安全使用。

答案 1 :(得分:3)

  

void * q =& x;

可能值得理解事物在记忆中的表现方式,以便您理解void*的含义。指针是内存中包含内存中另一个位置的位置。有关实际示例,请考虑以下代码:

int x = 4;
int* y = &x;
void* z = &x;

在我的64位系统上,我可以使用gdb来检查内存。结果如下表所示:

Address         | Memory Value                               | C expression
================================================================================
0x7fffffffdf8c  | 0x04 0x00 0x00 0x00                        | int x = 4;
0x7fffffffdf98  | 0x8c 0xdf 0xff 0xff 0xff 0x7f 0x00 0x00    | int* y = &x;
0x7fffffffdf90  | 0x8c 0xdf 0xff 0xff 0xff 0x7f 0x00 0x00    | void* z = &x;

我们在这看到什么?好吧,0x7fffffffdf8c0x7fffffffdf90被值0x04占用,我平台上的所有零 - 整数都是4字节宽,顺序是小端,所以字节是相反的一个人期望阅读的内容。然后,我们看到接下来的8个字节被x的地址占用,而第二个指针也是如此。

因此,使用指针的过程是读取地址的地址并使用它。听起来你可能对这个概念很满意,所以,继续:

指针的类型不会影响指针的大小。这是关键。查看上面的指针值,它们实际上都是相同的大小。这里的大小值是关于目标内存 - 它指示编译器加载并操作一定量(字节数 - 类型的大小/宽度)的内存。

正如其他人所说,

void*是“无类型的”。相反,它只是一个指针,并且编译器/ C语言将无法支持您解除引用它,因为没有类型信息 - 没有办法安全地告诉目标有多少内存你要阅读的地址。

然而,这个事实有时是有用的。使用类型的想法是在代码中提供一致性 - 如果函数需要64位整数,则使用类型强制执行此要求,这样就不会引入错误。但是,有时你不介意你得到什么类型。在这些情况下,您的要求是“一些记忆。任何记忆!” - 我能想到的最好的例子是memcpy - 这可能有点像这样:

void *memcpy(void * s1, const void* s2, size_t n)
{
    char *r1 = s1;
    const char *r2 = s2;
    while (n) {
        *r1++ = *r2++;
        -n;
    }
    return s1;
}

Adapted from uclibc。在这里,变量类型根本不重要 - 在内部,函数决定操纵sizeof(char)类型的内存(char通常但不总是字节宽)但它同样可以在{{ 1}}或其他一些值。这里所有类型都是控制从起始地址开始考虑的字节数,作为类型的一部分。

为了给你另一张表,这里是一些类型尺寸的比较:

uint64_t

你可能想知道为什么libc函数中没有强制转换 - 嗯,没有必要。所有指针的大小都相同,因此无需其他任何操作。

答案 2 :(得分:2)

ptrp的效果在两种情况下都是相同的,因为保证void *指针可以在演员表之间转换。

void *q = &x只会将x的地址存储在q中,而不关心x指向的内容。然后int *p = q将此地址分配给一个实体,该实体的语义描述它指向int

请注意,在这种情况下,操作是安全的,因为x的类型为intp的类型为int *。如果您将q分配给类型指针,例如double *,则情况不会如此。

答案 3 :(得分:1)

两个陈述是相同的,但第一个是首选,因为在第二个陈述中你摆脱了危险的类型。

类型的主要目的是阻止您分配不兼容的变量,例如苹果和汽车。

因此,

void* q = &x;

摆脱了x

的类型
int* p = q;

并且这个将未知类型转换为整数上的指针。您最好将q转换为(int *)以表示您已意识到危险。