首页 > 试题广场 >

在上下文及头文件均正常的情况下,以下代码打印的结果是(假设运

[单选题]

在上下文及头文件均正常的情况下,以下代码打印的结果是(假设运行在 64 位计算机上):

struct st_t {
    int status;
    short *pdata;
    char errstr[32]; 
};
st_t st[16];
char *p = (char *)(st[2].errstr + 32);
printf("%d", (p - (char *)(st)));
  • 32
  • 120
  • 114
  • 144
根据字节对齐,在64位系统下struct st_t 结构体占用的字节为48个。
struct st_t {
int status;  //占用8个(后面的4个为对齐位)
short *pdata;//占用8个
char errstr[32];//占用32个
};
char *p=(char *)(st[2].esstr+32),p实际指向了st[3]
p-(char *)(st)),即为&st[3]-&st[0],占用空间为3个结构体的大小,即3*48=144,选D
编辑于 2018-01-12 11:19:16 回复(4)
回答都是千篇一律,估计都是各种复制粘贴。。。就没人奇怪char *p=(char *)(st[2].esstr+32);中的esstr是啥吗?个人感觉是题目给错了,应该是char *p=(char *)(st[2].errstr+32);才对。
理由:
1、esstr,C/C++中并没有这个操作或关键字;
2、st是由结构体初始化的,st[2]中包含有结构体中的成员{int status;short* pdata;char errstr[32];}而符号“.”就是对象调用成员的符号,即"."后面应该是对象的成员。
所以我猜测正确的应该就是errstr。
知道了这一点,题目就好理解了,st[2].errstr表示指向errstr的首地址,因为errstr占32位空间,所以(st[2].errstr+32)表示指向st[2].errstr的最后一个元素的下一个地址,即st[3]的首地址。
所以p-(char *)(st)),即为&st[3]-&st[0],占用空间为3个结构体的大小,即3*48=144,
发表于 2018-08-03 13:18:29 回复(12)
这个是题目的地址分配
32位环境  4字节对齐 指针占4字节
64位环境  8字节对齐 指针占8字节
因为是64位环境下
int status;虽然int只占用4个 由于后面的指针八个字节放不下 填补不了空位 所以对其要八个字节
short *pdata; 这个指针会占用8个字节
char errstr[32]; 占用32个字节
所以一共占用 8+8+32=48个字节
char *p=(char *)(st[2].esstr+32),p实际指向了st[3]
则p-(char *)(st)),即为&st[3]-&st[0],占用空间为3个结构体的大小,即3*48=144,


编辑于 2017-11-20 11:42:33 回复(0)
若在64位机器上,指针占8字节,字节对齐后一个结构体占48字节,所以结果为48+48+16+32=144
若在32位机器上,指针占4字节,字节对齐后一个结构体占40字节,所以结果为40+40+8+32=120

发表于 2017-08-16 23:01:38 回复(4)
没有一个解答我能看懂的
发表于 2017-08-30 10:54:23 回复(1)
structst_t {
    intstatus;  0 ~ 3// int是4  (3-0+1=4)
    short*pdata; 4 ~ 11 // 64位指针是 8    (11-4+1=8) 
    charerrstr[32]; // 12 ~ 48 // 12 + 32 = 44 ,结构体的大小要是内部最大成员的整数倍 ,8 的整数倍。所以对齐到48
};
char *p=(char *)(st[2].esstr+32)   指针指向地址的开头,st[2].esstr其实指向的是st[2]的char数组的开头。。,+32以后移动到了自己的末尾。也就是st[3]的开头
p-(char *)(st))      st指向的是st[0]的开头。。
所以一减 就是 3X48=144了。
(仅供参考。)
发表于 2017-09-11 17:22:27 回复(3)
看看这个https://www.cnblogs.com/jiashan/p/4782808.html
发表于 2018-07-14 16:54:22 回复(0)
结构体占48.P指向3相乘144
发表于 2021-11-22 08:21:46 回复(0)
指针即为地址,指针几个字节跟语言无关,而是跟系统的寻址能力有关,譬如以前是16为地址,指针即为2个字节,现在一般是32位系统,所以是4个字节,以后64位,则就为8个字节。
发表于 2019-04-04 20:14:04 回复(0)

为什么要字节对齐?

Key points: 需要字节对齐的根本原因在于CPU访问数据的效率问题.

如果你非得节省空间,可以安排一下变量的顺序。

FBI Warning: 将指针强制类型转换时,很可能破坏对齐,导致效率下降(on X86) or error(on MIPS)

发表于 2018-09-22 21:50:30 回复(0)
#include <iostream>
using namespace std;
struct cs
{  //              成员大小       偏移量
    short a;  //       2             0
    char b;  //       1            0+2=2
    float c;  //       4            2+1-->4
    // 结构体大小等于最后一个成员c的偏移量4加上最后一个成员c的大小4,4+4=8
};
/* short占2个字节,char占1个字节,float占4个字节。 介绍相关概念——偏移量。
偏移量指的是结构体变量中成员的地址和结构体变量地址的差。
结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。
显然,结构体变量中第一个成员的地址就是结构体变量的首地址。
因此,第一个成员a的偏移量为0。
第二个成员b的偏移量是第一个成员的偏移量0加上第一个成员的大小2,
即(0+2),其值为2,
第三个成员c的偏移量是第二个成员b的偏移量2加上第二个成员b的大小1,
即(2+1),其值为3,
由于结构体变量中成员的偏移量必须是成员大小的整数倍,所以3-->4;
结构体大小等于最后一个成员c的偏移量4加上最后一个成员c的大小4,
即(4+4),其值为8。
*/
/* 存储变量时地址要求对齐,编译器在编译程序时会遵循两条原则:
(1)结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍) 
(2)结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数。
*/
int main()
{
    cout<<sizeof(cs)<<endl;// 8
    return 0;
}
发表于 2018-08-30 16:04:52 回复(0)
cpp的题目放java来了
发表于 2017-08-12 19:00:34 回复(0)
发表于 2023-05-01 22:03:17 回复(0)
考查字节对齐以及指针
st_t 结构体大小为 8 + 8 + 32 = 48
指针p实际指向的就是st[3]的首地址
3 * 48 = 144
发表于 2021-07-22 23:19:27 回复(1)
64位是指针8位,不是144吗
发表于 2017-08-14 21:27:48 回复(0)
首先我们知道结构体st_t占了48bit,st[2].errstr当前指的地方在 st[0] + st[1] + (st[2].int+4补齐)+st[2].short 的后面,此处未算上st[2].errstr的32bit,所以在加上32bit之后。你可以把char *p后面的式子当作 st[0] + st[1] + st[2] = 3 * 48bit = 144bit。
发表于 2024-08-23 11:11:58 回复(0)
地址相减,显示出来的是字节差,不是位差
编辑于 2024-03-18 10:40:17 回复(0)
48*3
发表于 2023-12-31 14:18:38 回复(0)
我运行的结果是120
编辑于 2023-12-16 20:32:30 回复(0)
首先是字节对齐,此结构体是48字节 (char *)(st[2].errstr + 32) 这里表示 数组名+32 地址+32,就到了
st[3]的位置,所以是st[3]与st[0]的地址差
发表于 2023-09-09 10:04:58 回复(0)