有人可以向我解释一下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");
答案 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
虽然满足编译没有错误,但不足以包含完整地址。