C 为什么要抛出指针?
也许我用我的例子把人们弄糊涂了。我试图理解代码的一部分,并将其简化。这是原始代码的一部分(再次简化…:)(见下面的原始帖子) 所以我想知道,为什么他们要铸造已经是uint8_t的pbuf。但我想我现在已经得到了答案 ------------旧职位------------- 我正在探索北欧半导体nRF24LE1 如果我有以下测试代码C 为什么要抛出指针?,c,embedded,C,Embedded,也许我用我的例子把人们弄糊涂了。我试图理解代码的一部分,并将其简化。这是原始代码的一部分(再次简化…:)(见下面的原始帖子) 所以我想知道,为什么他们要铸造已经是uint8_t的pbuf。但我想我现在已经得到了答案 ------------旧职位------------- 我正在探索北欧半导体nRF24LE1 如果我有以下测试代码 void tempF(int *test) { int varA; int varB; int varC; varA = *(int
void tempF(int *test)
{
int varA;
int varB;
int varC;
varA = *(int*)(&test); // The way it is done in the source code
varB = *(&test);
varC = test;
printf("A: %x\n", varA);
printf("B: %x\n", varB);
printf("C: %x\n", varC);
printf("C1: %x\n", test);
if (test == 0x00)
printf("equals 0x00");
}
int main(void) {
int myArray[3];
tempF(myArray);
return 0;
}
printfs都给出了相同的答复。
“瓦拉风格”的原因是什么?有必要的例子
如果我使用varA中的方法,我不会得到警告“warning C260:'='”:指针截断。问题是,任何指针类型都不需要与
int
大小相同。编译器会提醒您这一事实
使用(int*)(&test)
将测试地址强制转换为指向int的指针。
取消对它的引用会产生一个
int
,可以愉快地分配给int
变量。如果指针需要的位数超过int所能容纳的位数,它可能仍然会被截断,但您可以说服编译器,您确实知道自己在做什么,而且这是出于目的而发生的。假设您的示例变量实际上是int
:
int varA;
int varB;
int varC;
如果不使用GCC编译器版本4.4.7或更新版本,并且如注释中所述使用stdio.h
,则代码不会编译,您的后两条语句将因非法类型“int”和“指向int的指针”而出错
varA = *(int*)(&test); // The way it is done in the source code
varB = *(&test);//error
varC = test; //error
如果它们是int*
int *varA;
int *varB;
int *varC;
然后第一条语句:varA=*(int*)(&test);
将出错
赋值语句编译的唯一方法是使用声明如下的变量:
int varA;
int *varB;
int *varC;
varA = *(int*)(&test); // The way it is done in the source code
varB = *(&test);
varC = test;
您的三个示例基本上都在将指针转换为
int
。从技术上讲,这需要在您的案例B
和C
中进行强制转换,并且您的编译器应该警告您这一点。例如:
int varC = (int) test;
对于强制转换,这是完全有效的,但是没有,没有。然而,编译器可能会生成相同的代码,有或没有
但是,在您的示例代码中,&test
表达式的类型是int**
。将该类型的表达式强制转换为int*
并取消对结果的引用,就像将值分配给varA
一样,旨在将test
的字节重新解释为int的字节代码>,如C++ +代码> RealTytPase。这不一定产生与将代码> >测试< /C> >直接转换成<代码> int >代码>的相同值,如将值赋给<代码> VARC < /C>。如果目标大小与目标系统上的<代码> int >代码大小不一样,则它们特别容易不同。em,但即使大小相同,也不要求它们产生相同的结果
另一方面,将*
运算符直接应用于&
运算符的结果没有净效果,因此为varB
计算的值将可靠地与为varC
计算的值相同(&test);
表示将测试的按位表示解释为int
,然后将其存储在var
中
强制转换((int*)
)表示测试的按位表示应解释为
,这与C Caster的效果不同。@约翰伯林格:你是对的,我想在查看代码后删除我的评论,但是现在我还是把它留在这里,如果其他人得到相同的想法。@约翰伯林格-我的编译器错误,写代码的方式,你能编译吗?我添加了,而int
运算符将其解释为*
int
这与,如果memcpy(&varA,&test,sizeof varA);
您确定sizeof(int)==sizeof(int*)
不是var的类型吗?
?您的三种情况都没有任何意义。如果您想打印地址,那么只需使用int*
说明符,而不在两者之间进行任何转换,就更好、更安全了。如果您想将指针存储为整数,请不要使用int来存储指针,我们(u)intptr_tI有一种感觉%p
,其他人实际上是OPs实际代码中的varA
。@Groo,我倾向于不这样认为。重点似乎是将指针值转换成int*
。你会在各种C代码中看到这种转换方法。在这些情况下,它的作用与C++ >代码> RealTytRaskint
,然后OP的代码用GCC 4.4.7为我编译,但是我确实收到了关于#include
和varB
@ryyker为我编译的任务的警告,并带有警告(以及includevarC
)使用GCC4.5.1,但它编译runs@rykker,正如我在您的回答中所回答的那样,如果我预先编写了stdio.h
,那么代码将在GCC 4.4.7中为我编译#include
。编译器会警告GCC-std=c99
和varB
的赋值中存在隐式指针转换,我还指出ut在我的回答中。分配给varC
的表达式,这是主要的观点,在我看来很好,GCC对它没有抱怨,即使所有警告都打开了。你认为它有什么问题?@JohnBollinger-是的,谢谢你,我看到了你下面的评论。你认为它有什么问题吗?即使是varA
也添加了C99扩展打开时,我的编译器无法编译原始的操作代码。那么GCC编译器是否可能使用尚未被标准采用的扩展?@rykker,GCC不一定保证拒绝依赖标准扩展的程序,即使使用(例如)stdio.h
,因此它是可能的-std=C99
int varC = (int) test;