【问题标题】:How to subtract a hex from a strlen return then add to a hex address?如何从 strlen 返回中减去十六进制然后添加到十六进制地址?
【发布时间】:2018-03-30 16:36:28
【问题描述】:

我想检查一个字符串长度,然后减去 0x3(十六进制);然后添加到存储为十六进制的地址;然后将结果以十六进制形式放入地址中。 地址存储在无符号长整数中。

struct node { unsigned long int address;  char operand_1[12];};

它是这样工作的吗:

(0x)seekNP->address = (0x)seek->address +(( (0x)strlen(seek->operand_1)) - 0x3);

或类似:

seekNP->address = seek->address +((strlen(seek->operand_1)) - 0xF);

我知道所有数字最后都以二进制形式存储,也许我的问题也应该是当我在十六进制和十进制 size_t 返回类型甚至十进制之间执行算术时会发生什么?

它们是否都自动转换为二进制然后对二进制执行操作?

编辑:说char Operand_1 = "1000";,我通过seek->address = strtol(seek->operand_1,NULL,16);将它存储在unsigned long address 添加strlen返回值会正确增加十六进制变量(地址)值吗?

编辑 2:好的,因为脱离上下文命名变量地址令人困惑,可以说 unsigned long int address; 是 -> unsigned long int MIKE;

【问题讨论】:

  • 您自己说您知道所有数字都以二进制形式存储。这意味着除了表示之外,十六进制、十进制、八进制和二进制数字格式之间实际上没有区别。十六进制值0x03 等于十进制3 等于八进制03 等于二进制101。所以你真的不能将变量(如seekNP->address)中的值“转换”为十六进制,这没有任何意义。
  • 没有转换,它只是二进制。以十六进制查看数字只是查看数据的众多方法之一。与二进制加法相比,十六进制加法没有特殊的电路
  • 顺便说一句,将字符串的数字长度添加到变量 unsigned long int address 中存储的值中,不会更改该变量在内存中的地址。
  • @ryyker 没有添加到地址中,我添加到了名为地址的变量中。
  • @topcat address 字段是否包含其他变量的地址?如果是这样,这表明您的代码中存在另一个潜在问题,因为地址不应存储在 unsigned long 中。

标签: c hex decimal strlen


【解决方案1】:

首先,符号(0x)seekNP->address 是无效的C。您可能会想到typecast,其中一个变量的类型被转换为另一个变量。无论如何:

seekNP->address = seek->address +((strlen(seek->operand_1)) - 0xF);

是正确的说法。 (假设确实有一个seek->address它在语法上是正确的。否则,(假设显示的结构)这个似乎更可能是你的意思:

struct  { 
    unsigned long int address;  
    char operand_1[12];
}seekNP;
....    

//  interger    =         integer         - integer    
seekNP->address = strlen(seekNP->operand_1) - 0xF; //seems more correct given 
                                                 //the variable you are showing.  

为了澄清,正如 cmets 中提到的,int 的所有形式都以二进制形式存储在内存中。可视化表示(即无论是格式化将其值呈现为decimalhexadecimal 还是octal 对内存中存储的值没有影响。因此,C 语句可以在其语句中混合和匹配各种形式的整数,而无需担心内存中的结果值会受到影响。

int sum = 103 + 1003 + 10003;
int sum = 0x67 + 0x3eb + 0x2713

两者都导致111090x2B65

【讨论】:

  • 我不是添加到变量的地址,我是添加到变量中。该变量只是命名为地址。
  • @topcat - 好的,变量命名把我扔了。我已经编辑了答案。
【解决方案2】:

这是一个做加法的简单例子,减法也是一样的。

请注意,当您让编译器完成工作并使用数据类型和指针时,算法会为您处理... +1 或 -1 到您的 指针 是移动到您的下一个项目不必担心您的数据是 1 字节、2 字节还是 8+ 字节。

看起来您正在自己完成所有工作,将地址保存在 unsigned long 的变量中,您认为这是理所当然的 64 位寻址{或者如果您只做了 unsigned int,那就是 32 位寻址,希望如果您有超过 2^32 个字节的可寻址空间},您就会认识到这个问题。所以我的建议是使用指针,尤其是在处理超过 1 个字节的数据时。

unsigned long *pAddress; 表示 pAddress 保存一个地址值,因为它被定义为带有* 的指针,并且它指向内存中的无符号长整数类型的数据。内存中有多少字节是 unsigned long 的值,这取决于您的系统,并且是在系统级别处理的事情,您通常不需要或应该必须担心。但在今天的计算机上,它可能是 64 位或长整数。

我认为一旦你了解了它的工作原理,它就会变得容易:

#include <stdio.h>

int main ( int argc, char *argv[] )
{
   char a[8];
   short int b[8];
   int c[8];
   long int d[8];
   float e[8];
   double f[8];

   char *pa;
   short int *pb;
   int *pc;
   long int *pd;
   float *pe;
   double *pf;

   pa = a;
   pb = b;
   pc = c;
   pd = d;
   pe = e;
   pf = f;

   printf(" address of a is   %p\n", pa );
   printf(" address of b is   %p\n", pb );
   printf(" address of c is   %p\n", pc );
   printf(" address of d is   %p\n", pd );
   printf(" address of e is   %p\n", pe );
   printf(" address of f is   %p\n", pf );
   printf("\n");
   printf(" address of a+1 is %p\n", pa+1 );
   printf(" address of b+1 is %p\n", pb+1 );
   printf(" address of c+1 is %p\n", pc+1 );
   printf(" address of d+1 is %p\n", pd+1 );
   printf(" address of e+1 is %p\n", pe+1 );
   printf(" address of f+1 is %p\n", pf+1 );
   printf("\n");
   printf(" sizeof( char )      is %ld\n", sizeof( char ) );
   printf(" sizeof( short int ) is %ld\n", sizeof( short int ) );
   printf(" sizeof( int)        is %ld\n", sizeof( int ) );
   printf(" sizeof( long int )  is %ld\n", sizeof( long int ) );
   printf(" sizeof( float )     is %ld\n", sizeof( float ) );
   printf(" sizeof( double )    is %ld\n", sizeof( double ) );

   printf("\n");

}

【讨论】:

  • 我认为根据您的说法:...只是 unsigned int 是 32 位寻址...,您实际上指的是 data type ranges,(与寻址相反)。变量的类型并不能确定它将用于哪个地址空间。即intlongfloatdouble 都可以在32bit64bit 寻址中使用。编译时设置将决定构建可执行文件以支持哪个寻址目标。
猜你喜欢
  • 2011-12-09
  • 2018-05-16
  • 1970-01-01
  • 2012-05-27
  • 2018-07-26
  • 2014-08-24
  • 2011-06-01
  • 2014-04-26
  • 1970-01-01
相关资源
最近更新 更多