2012-01-24 142 views
1

我看到一个非常奇怪的代码片段,我不太清楚,如果我的理解是正确的:指针运算C和浇铸

#include <stdio.h> 

int main(char *argc, char **argv) 
{ 
    char a[50]; 
    *(char *) (a + 2) = 'b'; // <== THE LINE WHICH CONFUSES ME 

    printf("value: %c\n", a[2]); 
    return 1; 
} 

是不是正确的,我们走2桶进一步施放“B”变成一个指向b的指针然后解引用它?

+0

你已经有了一些很好的答案。请记住,使用C语言,您可以享受安全编码和指针算术的优势 - 只需选择您想要的那个:) –

+1

'argc'参数实际上应该是'int'。在那里有计算机,'int'和'char *'具有不同的表示,使你的程序行为非常不明确。你也不用'argc'或'argv'做任何事情,所以最简单的事情就是不要声明它们:'int main(void){/ * ... * /}'。还有一点是,不同操作系统可以对返回值1进行不同的解释。首选'返回0;'或'返回EXIT_SUCCESS;'或'返回EXIT_FAILURE;'。 – pmg

回答

6

这是完全等价的

*(a + 2) = 'b'; 

演员是不必要的。

它所做的只是向阵列中添加两个指针,其中指针a的衰减,解引用结果指针,并将字符'b'指定给该内存位置。

a是指针时,代码a[x]完全等同于*(a + x)。所以在你的情况下,*(a + 2) = 'b'a[2] = 'b'完全一样。

1

您未投下'b'

您投(a+2)char*(它什么都不做,因为它已经char*),尊重它,并把它放在那里'b'

是的,我们进一步去2桶是正确的。

3

*(char *) (a + 2)

相当于

a[2]

根据定义,a[2]*(a + 2)a + 2的值已经是char *类型,所以a + 2char *的演员阵容,如(char *) (a + 2),是无操作。

+0

尽管在C中的指针类型(和C++中的指针类型之间的C风格转换)之间进行转换总是无操作:) –

1

不,你把a为指针,由两个增加它,然后将其转换为(char*)(废铸件,它已经是char*),取消对它的引用,然后存储'b'成。

它是完全相同的,因为这:

a[2] = 'b'; 
2
*(char *) (a + 2) = 'b'; // <== THE LINE WHICH CONFUSES ME 

这条线的字面意思是非常相同

a[2] = 'b' 

第一铸造(char*)是多余的,因为一已经是char类型。事实上,索引转换为增加和取消偏转,即

a[n] === *(a + n) 

关于C一个鲜为人知的事实:你可以写以及

n[a] 

,并得到同样的结果。