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

发布于 2024-12-19 09:34:07 字数 1554 浏览 2 评论 0原文

我正在尝试在 C++ 中生成 128 和 256 位整数,并注意到将 char** 转换为 int* 并将 int* 转换为 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;

那么,任何人都可以解释为什么它不是添加的指针的值而是添加的值被指向?

I'm trying to make 128 and 256 bit integers in C++, and noticed casting char** to int* and int* to int (and backwards) can be used to convert char arrays to integers and integers to char arrays.
Also, char* + int works fine.

However, when I try char* + char* the compiler tells me the types are invalid. Is there any workaround for this, or will I have to write my own functions for the operators?

For example:

int32_t intValue = 2147483647;
char *charPointer = *( char** ) &intValue;
charPointer += 2147483647;
charPointer += 2;
cout << ( *( int64_t* ) &charPointer )  << endl;

output: 4294967296

Basically, what I do should be something like the following:

int32_t intValue = 2147483647;

somewhere in memory:

[ 05 06 07 08 09 0A 0B 0C ] ( address, in hex )
[ .. .. FF FF FF 7F .. .. ] ( value, in hex )

then:

char *charPointer = *( char** ) &intValue;

somewhere in memory:

[ 58 59 5A 5B 5C 5D 5E 5F ] ( address, in hex )
[ .. .. 07 00 00 00 .. .. ] ( value, in hex )

then:

charPointer += 2147483647;

I honestly have no idea what happens here.
It seems like it does something like this though:

[ 05 06 07 08 09 0A 0B 0C ] ( address, in hex )
[ .. .. FF FF FF FE .. .. ] ( value, in hex )

then:

charPointer += 2;

Same here.
Something like this:

[ 05 06 07 08 09 0A 0B 0C ] ( address, in hex )
[ .. .. 00 00 00 00 01 .. ] ( value, in hex )

And at last I just print it as if it were an 8 byte integer:

cout << ( *( int64_t* ) &charPointer )  << endl;

So, can anybody explain why it isn't the value of the pointer that is added but the value of what's being pointed to?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

舞袖。长 2024-12-26 09:34:07

这些转换确实存在,但它们并没有按照您的想法进行。将指针转换为整数只是将其视为整数;它没有做任何实际的“数学”。例如,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'<的内存位置/code> (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;

这有意义吗?

These conversions exist, but they don't do what you think they do. Converting a pointer to an integer is just treating it as an integer; it's not doing any actual "math". For example, char * s = "abcd"; int i = (int) s; will not give the same result every time, because s and i are both just the memory address that the string starts at. Neither has anything to do with the actual contents of the string.

Similarly, char* + int is just taking an offset. To write char * s = "abcd"; char * t = s + 2; is just another way to write char * s = "abcd"; char * t = &(s[2]);; that is, s is the memory location of the 'a', and t is the memory location of the 'c' (s, offset by two char-widths, that is, two bytes). No actual math has taken place, except in the sense that "pointer arithmetic" requires math to compute byte offsets and find memory locations.

char * + char * doesn't make sense: what would it mean to "add" two memory locations together?

Edit: Here is the code you added to your question:

int intValue = 5198;
char *charValue = *( char** ) &intValue;
charValue += 100;
cout << ( *( int* ) &charValue )  << endl;

Let me expand it a bit, so it's a bit clearer what's going on:

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;

Does that make sense?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文