【问题标题】:Separating digits of integer using pointers使用指针分隔整数的数字
【发布时间】:2015-04-15 06:49:42
【问题描述】:

我有一个整数(i)占用4个字节,我假设它是这样存储在内存中的,起始地址为1000,

如果我写int*p=&i;

p 现在存储起始地址,这里是 1000。

如果我增加 p 它指向地址 1004.

有没有办法遍历地址 1000、1001、1002 和 1003,以便我可以使用指针分隔和打印数字 1、5、2、6? 请帮忙..... :((新手)

我对存储的假设可能是错误的 谁能帮我纠正一下? :(

编辑 1

根据下面Mohit Jain给出的答案和其他人的建议,

unsigned char *cp = reinterpret_cast<unsigned char *>(&i);
for(size_t idx = 0; idx < sizeof i; ++idx) {
  cout << static_cast<int>(cp[idx]);
}

我得到的答案是 246 5 0 0 .

我意识到我假设内存结构的方式是错误的, 那么有没有办法使用指针获取实际数字??

【问题讨论】:

  • i的类型是什么?您可以使用 char * 类型的指针来逐字节遍历内存。
  • 请注意,整数是二进制编码的,因此十进制数 1526 编码为 0x000005F6(假设为 32 位 int) - 您将在字节中看到的值是 0、0、5 和0xF6/246 - 可能是另一个顺序(由于endianness)。数字 0x01050206 将在大端机器上存储为您的插图 - 十进制值为 17105414 - 或 0x06020501=100795649 在小端机器上。
  • 您在问题中说明的布局称为binary-coded decimal。它偶尔用于特殊目的,但它不是在典型计算机上用于通用计算的整数表示方式。
  • 更新了我的问题...请检查:(
  • @DeepN "那么有没有办法使用指针来获取实际数字??" 你不需要指针,你只需使用/除法(除以 1000,100,10)和% 取模以确定十进制数字。

标签: c++ pointers


【解决方案1】:

具有值1526int 通常不会存储为具有值1526 的四个字节。

相反,它将以二进制形式存储。假设一台 little-endian 机器,字节将具有以下值:0、0、5、246(如果它是 big-endian,您将以相反的顺序获得相同的值)。这些数字的原因是它可以在每个字节中存储从 0 到 255 的值。因此,它存储为 5 * 256 + 246。当像这样处理内存中的值时,使用十六进制而不是十进制通常很方便(并且很常见),在这种情况下,您会将其视为 0x05F6。

获取十进制数字的常用方法涉及比指针更多的数学运算。例如,最低有效位将是该值除以 10 后的余数。

【讨论】:

    【解决方案2】:

    列出内存内容

    使用指针(依赖于字节序的输出)

    unsigned char *cp = reinterpret_cast<unsigned char *>(&i);
    for(size_t idx = 0; idx < sizeof i; ++idx) {
      cout << static_cast<int>(cp[idx]);
    }
    

    不使用指针(与字节序无关的输出),因为数字的存储方式与您假设的不同。

    int copy = i;
    unsigned int mask = (1U << CHAR_BIT) - 1U;
    for(size_t idx = 0; idx < sizeof i; ++idx) {
      cout << (copy & mask);
      copy >>= CHAR_BIT;
    }
    

    列出数字

    如果你想要使用指针的整数位数,你应该首先将整数转换为字符串:

    std::string digits = std::to_string(i);  // You can alternatively use stringstream
    char *p = digits.c_str();
    for(size_t idx = 0; idx < digits.length(); ++idx) cout << (*p++);
    

    【讨论】:

    • 无法从 'int *__w64 ' 转换为 'unsigned char *' :( 使用这一行 unsigned char *cp = &i;
    • 您需要使用reinterpret_cast。让我更新答案。
    • 是的,我现在得到了答案,但它不是我想要的 :( 我正在更新问题......无论如何都赞成,
    【解决方案3】:

    您可以将指针强制转换为 (char *) 并递增该指针以指向各个字节的开头。但是,您对存储的假设是错误的,因此您不会得到这样的数字。

    【讨论】:

      【解决方案4】:

      正如我所见,您想提取数字的每个数字。 要实现它,您需要:

      1. 得到提醒i除以10。这样做:const int r = i % 10;
      2. i除以10:i /= 10;
      3. 如果i不为0,则转到1。

      实现(未测试)可能是这样的:

      do
      {
           const int r = i % 10;
           // do anything you need with r
           i /= 10;
      } while (i > 0);
      

      这将为您提供从较低位开始的每个数字。

      【讨论】:

      • 感谢您的更新,我知道这种方法,我只是在尝试使用指针......但事实证明这是不可能的......
      • 如果您想将 int 划分为字节,那么您的方法是正确的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 2012-05-16
      • 2019-09-19
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多