我如何决定将Asterisk放在哪里?

时间:2014-03-09 15:52:52

标签: c pointers

这些线会不会这样做?如果没有,有什么区别?我如何决定把星号放在哪里?

#define OUT1 *((portptr ) SIGDATA_ADR)

#define OUT1 ((portptr *) SIGDATA_ADR)

好的,抱歉模糊的问题描述。 我要做的是一个连续读取两个开关的值,进行异或,并将其放在LED斜坡上的功能。

我的程序看起来像这样;它应该工作。

typedef unsigned char *port8ptr; 

#define OUT *((port8ptr) 0x400) 
#define IN1 *((port8ptr) 0x600) 
#define IN2 *((port8ptr) 0x601) 


 void DipSwitchEor( void ) 

{ 
  while( 1 )
  { 
    OUT = IN1 ^ IN2; 
  } 
} 

所以我很好奇我是否可以写#define OUT ((port8ptr *) 0x400)。我的答案很复杂。

3 个答案:

答案 0 :(得分:0)

OUT1OUT2的定义在语义上并不相同。

  • 在第一种情况下,SIGDATA_ADR被强制转换为指针类型portptr,然后解除引用,因此第一种情况下OUT1()的参数是指向的数据SIGDATA_ADR。这是有道理的,可能是正确的语义 - 给你后续的用例示例,它肯定是正确的。

  • 在第二种情况下,(portptr*)是指向指针的指针,第二种情况OUT1()SIGDATA_ADR的参数转换为指向指针的指针 - 这似乎不太可能。

请注意,在第一种情况下,*取消引用运算符,第二种情况下,它不是运算符,而是数据类型修饰符。它们不是同一个东西 - 它们碰巧由同一​​个角色代表 - 上下文就是一切;理解这可能使得确定哪个更正确更简单。

答案 1 :(得分:0)

这两个宏定义之间存在巨大差异

#define OUT *((port8ptr) 0x400)
#define OUT ((port8ptr*) 0x400)

第一个先生成一个指向内存地址port8ptr的{​​{1}}(强制转换),然后取消引用此指针(括号外的0x400运算符)以产生{{1位于内存地址*

第二个指针指向指向内存地址unsigned char的{​​{1}}。结果与使用0x400声明的变量port8ptr具有相同的类型。也就是说,结果是指向0x400 的双指针,当存储在地址foo的指针指向的位置时,char位于内存中。

答案 2 :(得分:0)

如果您只需要告诉各种C声明构造的含义,我认为您应该尝试http://cdecl.org。它也是一种可以安装在计算机上的实用程序。您的示例可能是您想要的是下面的代码,假设0x600,0x601和0x400是您的寄存器的地址:

void dip_switch() {
    unsigned char *in1 = 0x600;
    unsigned char *in2 = 0x601;
    unsigned char *out = 0x400;
    *out = (*in1) ^ (*in2);
}

使用#define只会在这种情况下咬你。你可能应该避开它。