在c++中使用char数组作为数学中的数字

Using char array as number for math in C++

本文关键字:数字 数组 c++ char      更新时间:2023-10-16

我试图在c++中制作128位和256位整数,并注意到将char**转换为int*int*转换为int(和向后)可用于将字符数组转换为整数和整数转换为字符数组。此外,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;不会每次都给出相同的结果,因为si都只是字符串开始的内存地址。两者都与字符串的实际内容无关。

同样,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;

明白了吗?