下面应该输出什么?

objectprogram 2003-11-09 08:29:17
#include<iostream.h>
void main(){
char str[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
char ch = *((short *)str + 3);
cout<<ch<<endl;
}

输出是什么啊?
...全文
40 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
TianGuangZao 2003-11-10
  • 打赏
  • 举报
回复
plainsong(短歌):
对,是 short int,程序有一点小毛病。
char ch = *((short *)str + 3);
cout<<ch<<endl;
改成:
cout << (int)ch << endl;
minghui000 2003-11-10
  • 打赏
  • 举报
回复
语法错误
短歌如风 2003-11-09
  • 打赏
  • 举报
回复
是个隐式类型转换。*((short *)str + 3)的类型是一个short。
#include<iostream>
using namespace std;

void main(){
char str[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
cout << sizeof(*((short *)str + 3)) << endl;
char ch = *((short *)str + 3);
cout<<ch<<endl;
cin.get();
}
输出是2。

还可以这样试一下:

#include <iostream>
#include <typeinfo>

using namespace std;
template<typename T>
char const * Typename(T x)
{
return typeid(x).name();
}

void main()
{
char str[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
cout << Typename(*((short *)str + 3)) << endl;
char ch = *((short *)str + 3);
cout<<ch<<endl;
cin.get();
}
输出是short。
TianGuangZao 2003-11-09
  • 打赏
  • 举报
回复
“你忘了一点,就是被解引用的不是一个char*,而是short*”
我一直不明白的就是这个问题。但我还是不敢确定是否得到的是 short。
因为
char ch = *((short *)str + 3);
编译器没给我任何提示信息,难道是隐式转换。

高尾端还是低尾端问题是我搞错了,我非科班,对底层实现知道甚少,我去找些资料补充一下,多谢指点。
短歌如风 2003-11-09
  • 打赏
  • 举报
回复
不过我前面正好把名词说反了:
I86是高尾端;在低尾端机器上输出是'\8'。
高尾端是指“整数的高字节存储到尾端”,低尾端则相反。

今天发烧,胡说一气,请大家见谅。
短歌如风 2003-11-09
  • 打赏
  • 举报
回复
TianGuangZao:
你忘了一点,就是被解引用的不是一个char*,而是short*,它的结果是short。所以并不是“取得该处的字符”,而是“取得该处的short”,因此已经与short的存储方式有关了。取出short后才又去转换为char,这时并不会管哪个字节是从内存中前面取出来的,只会取short的低字节。因此在低尾端和高尾端的机器上结果不相同的。

低尾端还是高尾端是一般是与硬件系统有关的。在I86系列的CPU中
Mov EAX, [EBX]这条指令会把[EBX]处的字节送到AL中,而[EBX + 3]处的字节送到EAX的最高位去,16位数同理。如果在这种机器上一定要实现“高尾端”的逻辑(应该是编译器决定而不是操作系统决定)也是可以的,但整数操作将会代价很大。
heibird 2003-11-09
  • 打赏
  • 举报
回复
对了!
TianGuangZao 2003-11-09
  • 打赏
  • 举报
回复
to yuantao(cfan):
(short*)str+sizeof(short)*3
相当于:
(short*)str + 6

太粗心了。


yuantao 2003-11-09
  • 打赏
  • 举报
回复
输出的应该是(short*)str+sizeof(short)*3地址出的字符
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
char str[10] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' };
char ch = *((short *)str + 3);
char ch1=*(str+3);
cout<<ch<<endl<<ch1<<endl;
system("PAUSE");
return 0;
}
输出的是g和d
从这个程序就可以看出来了
TianGuangZao 2003-11-09
  • 打赏
  • 举报
回复
((short *)str + 3) 对得到的地址解引用,取得该处的字符。
打错了,改成:
*((short *)str + 3) 对得到的地址解引用,取得该处的字符。
TianGuangZao 2003-11-09
  • 打赏
  • 举报
回复
谢谢短歌回复,让我学到两个新名词。不过在本例中好像不存在这种问题。

(short *)str + 3 是一个地址,相当于从数组首地址开始两个字节步长向后推移,((short *)str + 3) 对得到的地址解引用,取得该处的字符。所以并没有涉及 short int 在机器中的存储方式。

+---+---+---+---+---+---+---+---+---+---+
str| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |
+---+---+---+---+---+---+---+---+---+---+
|
|
(short *)str + 3


还有“低尾端”和“高尾端”好像是和操作系统有关的,而不是底层硬件系统,没记错的话, Linux 和 Windows 是相反的。

如果我的解释有错误,请指出。
短歌如风 2003-11-09
  • 打赏
  • 举报
回复
当sizeof(short)==sizeof(char)时,
*((short *)str + 3); 将取到str[6]和str[7]两个字节,并认为是一个short,这里就有一个问题:这两个字节分别是short的高字节和低字节,但不能确定哪个是高字节。

I86系统是“低尾端”存储,在存储一个short(到存储器)时,把低字节存储在低位,高字节存储在高位,而读取时也是同样的逻辑。按照这样的逻辑读出来,结果低字节就是7,高字节就是8,结果是0x807.

而“高尾端”的系统中,逻辑正好相反,认为str[7]中的是低字节,str[6]中的是高字节,结果就是0x708.

然后赋值给ch时要转换为char类型,会只保留低字节,所在在“低尾端”的机器上就是'\7',而在高尾端的机器上则是'\8'。
TianGuangZao 2003-11-09
  • 打赏
  • 举报
回复
plainsong(短歌):
在“高尾端”的机器上ch = '\8'。
不能理解,能否给讲一下,我觉得假定 short int 为 2 字节,应该只有一个答案 7。
flyingbirddhp 2003-11-09
  • 打赏
  • 举报
回复
是为7的吧~~~~~~~~~
wuyushu 2003-11-09
  • 打赏
  • 举报
回复
short *是强制转换,应该输出ASCII码为4的字符
wavebat533 2003-11-09
  • 打赏
  • 举报
回复
这不是必然的吗?
短歌如风 2003-11-09
  • 打赏
  • 举报
回复
上面的答案建立在sizeof(short) == sizeof(char)*2的基础上。
短歌如风 2003-11-09
  • 打赏
  • 举报
回复
在I86系统机上应该ch='\7',输出什么我就不知道了(这是一个控制字符)
在“高尾端”的机器上ch = '\8'。
pooryaya 2003-11-09
  • 打赏
  • 举报
回复
用VC6.0运行一下就知道了:)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧