【问题标题】:Modify byte with pointer用指针修改字节
【发布时间】:2013-04-25 17:45:59
【问题描述】:
long double i, *ptr;
ptr = &i;

我想修改第4个字节的值。long double的大小是8个字节。那么可以通过从 *ptr 中减去 4 来实现吗? 即

(ptr)-4 = 9;

【问题讨论】:

  • 您必须使用位运算符来提取字节,修改要修改的字节,然后重新组合它们。无论您是否使用指针,这都适用。顺便说一句,通常当人们想要这种字节提取/修改/重组的事情时,他们正在处理整数。您确定要将 i 设为浮点变量吗?
  • 实际上是指针概念的新手,上面的代码可能是错误的。我认为我取消引用上面的 ptr .. ptr-4 会做什么?
  • 不,ptr+1 不会访问第九个字节。如果 ptr 当前是地址 10,那么 ptr+1 将是地址 18,因为 sizeof(ptr) 为 8。请阅读eskimo.com/~scs/cclass/notes/sx10b.html,或 Vishy 的链接

标签: c++ c pointers


【解决方案1】:

您可以通过将指向对象的指针转换为指向unsigned char 的指针,然后通过该指针访问字节来访问表示对象的字节。例如,i 的第四个字节可以通过以下方式设置为 9:

unsigned char *p = (unsigned char *) &i;
*(p+4) = 9;

但是,您不应在没有充分理由的情况下这样做。它会遇到可移植性问题,并且应该仅用于特殊目的并仔细注意 C 标准和/或 C 实现的文档。如果您进一步解释为什么要这样做,可能会显示出更好的方法或解释危险。

请注意,第 4 个字节(第 0 个字节的起始编号)的正确地址是 p+4,而不是问题中使用的 p-4

【讨论】:

  • 谢谢,这正是我想要的:D
  • long double i, *ptr;指针 = &i;在这种情况下 (char *)+ptr 会做什么?
  • 我不确定你在问什么。如果您要问如果将数字添加到char * 会发生什么,那么答案是它会在地址中添加一些字节(在一定范围内)。如果你问别的,我不明白。 (char *)+ptr 不是一个有效的表达式,因为它包含 +ptr,并且您不能将一元 + 应用于指针。
【解决方案2】:

我会尝试一些更具可读性的东西

union {
    long double d;
    char v[sizeof(long double)];
} x;

x.d = 1234567890;
std::cout << x.d << ' ' << int(x.v[6]) << std::endl;
x.v[6] = 0xCC;
std::cout << x.d << ' ' << int(x.v[6]) << std::endl;

产量

1.23457e+09 44
1.23981e+09 -52

【讨论】:

  • 问题标记为 C。std::cout 在 C 中不存在。标准 C++ 中不支持通过联合的别名,就像在 C 中一样。
  • @EricPostpischil 它被 OP 以外的其他人标记为 C;我们实际上并不知道他们使用的是什么语言。
  • 你说得对,我手头有一个 C++ 项目并用它来测试。无论如何,这个建议也应该适用于 C。
  • @DarshanComputing:正如我的评论所指出的那样,无论哪种方式,代码都被破坏了:如果是 C,std::cout 不起作用。如果是C++,不支持通过union的别名。
  • @EricPostpischil 我不太熟悉标准。我想你可能是对的。具有我所知道的最严格标志的 g++ 不会抱怨,它工作得很好,所以我认为你最好指出这是否违反标准,但我仍然认为这是一个很好的答案。
【解决方案3】:

(*ptr)-4 = 9 是不允许的,因为它会导致 RValue 违规(赋值操作的右侧不能是另一个操作)。

但是你可以使用如下的位操作:

(*ptr) = (*ptr) &amp; 0x00009000;

【讨论】:

  • 抱歉打错了,它是ptr-4 = 9,简单来说我想修改内存的第4个字节。
  • ptr-4 = 9 仍然是一个操作。不是吗?
  • 那行不通; *ptrlong double&amp; 运算符未在 long double 上定义。
  • 如果你想修改内存的第 4 个字节,你可以使用我在回答中提到的格式来做到这一点。您可以更改相应的位。
  • GCC 编译器警告我看到的是:左值需要作为赋值的左操作数
【解决方案4】:

首先看这里:How do you set only certain bits of a byte in C without affecting the rest?。这个想法是清除您感兴趣的字节,然后使用或操作设置您的值。所以在你的情况下你会这样做:

val &= ~0xff;    // Clear lower byte
val |= 9 & 0xff; // Set Nine into the least significant byte. 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    相关资源
    最近更新 更多