指针问题或者说是疑问

kool86 2009-04-16 08:14:10
请看这里:
int x = 0;
char *p;
p = &x;
*p = 0x45;
p ++;
*p = 0x26;
那么:x = 0x2645;
相同情况的:
double y = 0;
int *f;
f = &y;
*f = 0x5678;
f ++;
*f = 0x8536;
那么:y = 0x85365678;
我想问的是这样的用法是否保险??
...全文
118 点赞 收藏 19
写回复
19 条回复
xiaocha 2009年04月16日
与机器相关的代码,只要lz知道自己在干什么,就可以用!
回复 点赞
Pekily 2009年04月16日
看下,觉得不安全!
不建议使用
回复 点赞
ies_sweet 2009年04月16日
这样的代码虽然在逻辑上可以,
但是不具备可移植性
因为在不同的机器上,
堆栈的生长方向是不同的。
所以说,
不建议搂主这样使用。

考虑到楼主的具体应用,
为什么不考虑使用 union 联合体 呢?
回复 点赞
fuzzy_man 2009年04月16日
double y = 0;
int *f;
f = &y;
*f = 0x5678;
f ++;
*f = 0x8536;
那么:y = 0x85365678;

楼主异想天开了,double类型占的8byte内存,里面存放确实是0x85365678的2进制数,但是你了解double类型每一个byte表示的含义吗?它们一部份存放整数部分,一部份存放小数部分,一部份存放指数。
回复 点赞
hurricane880 2009年04月16日
用一个指向char类型(占一个字节)的指针去操作存储int类型(占四个字节)的地址中的内容。其后果是很难预料的,很可能是灾难性的。会产生一个什么都不是的结果那是最好的结果。
举个简单的例子,假如我们定义20CM长的鱼(世界上所有的鱼——活着的)为hurricane880 : )
那么2只10CM长的鱼——活着的——显然不是hurricane880.
或者考虑更加糟糕的情况:一个本来20CM长的鱼被分成N份——显然已经是死了的——也不是hurricane880 :(
回复 点赞
kool86 2009年04月16日
谢谢各位前辈指点
回复 点赞
猫已经找不回了 2009年04月16日
int x = 0;
char *p;
p = &x;
*p = 0x45;
p ++;      //x有效区域只有4字节,默认++是根据p指向的类型来决定的,最好做一个类型转换,保证++位移字节数
*p = 0x26;

//此外,这样做,只能自己维护指针不要越界了.
回复 点赞
caodaxia 2009年04月16日
6楼正解,我也是这么理解的。
这个问题可以扩展到二维数组的指针问题。
int a[i][n],(*p)[n];
int b[i],*q;
a 的类型是地址,所存的变量大小是int*n ,a++就是把指针向后挪动了int*n个字节
b 的类型是地址,所存的变量大小是int, q++就是把指针向后挪动了int个字符
回复 点赞
allen1986 2009年04月16日
如果指针所指向的地址是你可以肯定的,而且是可以使用的,也就是说不是其他数据的地址,那问题不大,但如果你不肯定指针移动后指向的下一个地址是不是存有数据,就冒然的将它存放的值改变了,那么引起的问题可能就会很大。
回复 点赞
buyan2009 2009年04月16日
学习学习
回复 点赞
zgjxwl 2009年04月16日
#include <iostream>
using namespace std;

int main()
{
int x = 0;
cout<<"0x"<<hex<<x<<endl;
char *p;
p =(char*)&x;
*p = 0x45;
p ++;
*p = 0x26;
cout<<"0x"<<hex<<x<<endl;//按16进制输出
return 0;
}

你的x占4字节。char占1字节,强制转换后,是将对象x进行了切割。
你的p++每次只走一个char的大小,也就是一个字节。所以*p每次修改的都是一个字节的东西
你给*p赋了两次值,也就是说,将x里的两个字节都改动了,x里的两个字节被改变了。两个没变。
你这样写。。谁还敢用x?
回复 点赞
yyunffu 2009年04月16日
对于固定连续的内存块,按比例访问,应该没有问题吧。
学习!
回复 点赞
kool86 2009年04月16日
我用过了一次,也是可以的,不过有警告
我觉得对于目标地址来说,指针是他的整数倍,应该问题不大啊,如果没有越界,就好办
回复 点赞
traceless 2009年04月16日
的确很不保险,除非你知道这个地址是用来做什么的

像端口操作之类的话,才直接用已知地址的
回复 点赞
mengde007 2009年04月16日
语法上可以;但是实际操作不行;
回复 点赞
OenAuth.Core 2009年04月16日
肯定不保险,尤其是
f ++;
*f = 0x8536; (上面p的也一样)

这一句,直接操作一个你根本就不太清楚的地址,很危险
回复 点赞
kool86 2009年04月16日
我是在一个小工程里面用到的,没想到在这里引出了那么多的问题,工程里面虽然可以使用,
但就像你们说的,太危险了,
所以以后还是不要这样用了
回复 点赞
123qweasdzxc 2009年04月16日
[Quote=引用 14 楼 ies_sweet 的回复:]
这样的代码虽然在逻辑上可以,
但是不具备可移植性
因为在不同的机器上,
堆栈的生长方向是不同的。
所以说,
不建议搂主这样使用。

考虑到楼主的具体应用,
为什么不考虑使用 union 联合体 呢?
[/Quote]
正解!
回复 点赞
warren258 2009年04月16日
严重不建议使用,用来用去机器永远不会晕,晕的是lz
回复 点赞
发动态
发帖子
C语言
创建于2007-09-28

3.2w+

社区成员

24.0w+

社区内容

C语言相关问题讨论
社区公告
暂无公告