C和除法地址变量

时间:2017-05-14 20:56:21

标签: c clang

有人可以向我解释一下C中的对齐方式。 我是C语言的初学者,我完全不知道如何使用它。

main(){
  int i1 = 1, i2 = -1;
  unsigned int ui1 = 1, ui2 = -1;
  long l1 = 2, l2 = -2;
  unsigned long ul1 = 2, ul2 = -2;
  float f1 = 2.5;
  double d1 = 2.5;
  char c = 'A';
}

我必须检查所附程序代码中各个变量的地址是否可被整除:2,4和8。

这如何与变量的大小和对齐方式相关?

我将对这个合乎逻辑的解释表示感谢。

额外代码(从评论转录):

if( *w_i1 % 2 == 0 )
{
    printf("Address of i1 divisible by 2\n");
}
else
    printf("No by 2\n");
if( *w_i1 % 4 == 0 )
{
    printf( "Address of i1 divisible by 4\n" );
}
else
    printf("No by 4\n");
if( *w_i1 % 8 == 0 )
{
    printf( "Address of i1 divisible by 8\n" );
}
else
    printf("No by 8\n");

2 个答案:

答案 0 :(得分:1)

首先这样做:

printf( "var %s is %d wide at %x\n", "i1", sizeof( i1 ), &i1 );

对于每个变量。现在您已经打印了名称%s,它使用%d的字节数和变量的十六进制地址%x。下一步留给学生回答。 ;-)提示:在代码中进行数学计算,而不是计算器。

请注意,%x可能需要根据您的编译器而有所不同,请查看系统上printf的文档。

CPU以块的形式访问数据,也就是一组位。具体为1,2,4字节等。当变量与特定值(通常为浮点)对齐时,某些操作会更快。这可能不是对现代CPU的严格要求。如果是,编译器应自行进行调整。

答案 1 :(得分:0)

执行所描述的一种非常简单的方法是使用地址opertor(如您所评论的那样)和强制转换:

int main(void){

    int a;//create the variable
    int *pA;//create a pointer

    pA = &a;//use the pointer to get the variable's address
    //  cast to allow test
    (((uintptr_t)pA%2)==0) ? printf("even\n") : printf("odd\n");//#include <stdint.h> 
    //(((unsigned int)pA%2)==0) ? printf("even\n") : printf("odd\n");

    return 0;
}

注意使用uintptr_t。根据@Jonathan Leffler的评论,这个强制转换大到足以包含64位地址,其中unsigned int虽然满足编译没有错误,但不足以包含完整地址。