我试图在 C++ 中生成 128 位和 256 位整数,并注意到将 char**
转换为 int*
和 int*
to int
(和向后)可用于将 char 数组转换为整数以及将整数转换为 char 数组。
此外,char* + int
工作正常。
但是,当我尝试 char* + char*
时,编译器告诉我类型无效。是否有任何解决方法,或者我是否必须为运算符编写自己的函数?
例如:
int32_t intValue = 2147483647;
char *charPointer = *( char** ) &intValue;
charPointer += 2147483647;
charPointer += 2;
cout << ( *( int64_t* ) &charPointer ) << endl;
输出:4294967296
基本上,我所做的应该如下所示:
int32_t intValue = 2147483647;
内存中的某处:
[ 05 06 07 08 09 0A 0B 0C ] ( address, in hex )
[ .. .. FF FF FF 7F .. .. ] ( value, in hex )
然后:
char *charPointer = *( char** ) &intValue;
内存中的某处:
[ 58 59 5A 5B 5C 5D 5E 5F ] ( address, in hex )
[ .. .. 07 00 00 00 .. .. ] ( value, in hex )
然后:
charPointer += 2147483647;
老实说,我不知道这里发生了什么。
它似乎做了这样的事情:
[ 05 06 07 08 09 0A 0B 0C ] ( address, in hex )
[ .. .. FF FF FF FE .. .. ] ( value, in hex )
然后:
charPointer += 2;
这里也一样。
像这样:
[ 05 06 07 08 09 0A 0B 0C ] ( address, in hex )
[ .. .. 00 00 00 00 01 .. ] ( value, in hex )
最后我只是打印它就好像它是一个 8 字节整数:
cout << ( *( int64_t* ) &charPointer ) << endl;
那么,谁能解释为什么添加的不是指针的值,而是所指向内容的值?
这些转化存在,但它们并不像您认为的那样。将指针转换为整数只是将其视为整数;它没有做任何实际的“数学”。例如,char * s = "abcd"; int i = (int) s;
不会每次都给出相同的结果,因为 s
和 i
都只是字符串开始的内存地址.两者都与字符串的实际内容无关。
类似地,char* + int
只是取一个偏移量。编写 char * s = "abcd"; char * t = s + 2;
只是另一种写法 char * s = "abcd"; char * t = &(s[2]);
;即s
是'a'
的内存位置,t
是'c'<的内存位置
(s
,偏移两个 char
宽度,即两个字节)。除了“指针算术”需要数学来计算字节偏移量和查找内存位置之外,没有进行任何实际的数学运算。
char * + char *
没有意义:将两个内存位置“相加”意味着什么?
编辑:这是您添加到问题中的代码:
int intValue = 5198;
char *charValue = *( char** ) &intValue;
charValue += 100;
cout << ( *( int* ) &charValue ) << endl;
让我稍微扩展一下,以便更清楚地了解发生了什么:
int intValue = 5198;
int * intPtr = &intValue;
// intPtr is now the address of the memory location containing intValue
char ** charPtrPtr = (char**) intPtr;
// charPtrPtr is now the address of the memory location containing intValue,
// but *pretending* that it's the address of a memory location that in turn
// contains the address of a memory location containing a char.
char *charPtr = *charPtrPtr;
// charPtr (note: you called it "charValue", but I've renamed it for clarity)
// is now intValue, but *pretending* that it's the address of a memory
// location containing a char.
charPtr += 100;
// charPtr is now 100 more than it was. It's still really just an integer,
// pretending to be a memory location. The above statement is equivalent to
// "charPtr = &(charPtr[100]);", that is, it sets charPtr to point 100 bytes
// later than it did before, but since it's not actually pointing to a real
// memory location, that's a poor way to look at it.
char ** charPtrPtr2 = &charPtr;
// charPtrPtr2 is now the address of the memory location containing charPtr.
// Note that it is *not* the same as charPtrPtr; we used charPtrPtr to
// initialize charPtr, but the two memory locations are distinct.
int * intPtr2 = (int *) charPtrPtr2;
// intPtr2 is now the address of the memory location containing charPtr, but
// *pretending* that it's the address of a memory location containing an
// integer.
int intValue2 = *intPtr2;
// intValue2 is now the integer that results from reading out of charPtrPtr2
// as though it were actually pointing to an integer. Which, in a perverse
// way, is actually true: charPtrPtr2 pointed to a memory location that held
// a value that was never *really* a memory location, anyway, just an integer
// masquerading as one. But this will depend on the specific platform,
// because there's no guarantee that an "int" and a pointer are the same
// size -- on some platforms "int" is 32 bits and pointers are 64 bits.
cout << intValue2 << endl;
这有意义吗?