C函数替换参数特定索引中的字节
C function replace a byte in a specific index of a parameter
所以我使用以下代码:
unsigned long replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
int shift = 8 * indexToReplace;
unsigned long value = newByte << shift;
unsigned long mask = 0xff << shift;
return (~mask & original) | value;
}
我用|w|给定了一个词字节。
- 字节的编号从 0(最不重要)到 w/8-1(最重要
显着)。
例如:
replaceByte(unsigned long original, unsigned char newByte, int indexToReplace)
correct answer:
replaceByte(0x12345678CDEF3456, 0xAB, 2) --> 0x1234AB78CDEF3456
(my code's output is: 0x12345678CDAB3456)
correct answer:
replaceByte(0x12345678CDEF3456, 0xAB, 0) --> 0xAB345678CDEF3456
(my code's output is: 0x12345678cdef34AB)
我认为我需要检查系统是大端还是小端,因为我的代码更改了完全相反的字节。比方说它改变了 MSB 而不是 LSB。
但是...我意识到这并不重要,因为我正在使用位。
如你所见,这里的代码改错了索引:
(!) Error in index: 0. Output: 0x123456789abcdeff
Answer: 0xff3456789abcdeab
(!) Error in index: 1. Output: 0x123456789abcffab
Answer: 0x12ff56789abcdeab
(!) Error in index: 2. Output: 0x123456789affdeab
Answer: 0x1234ff789abcdeab
(!) Error in index: 3. Output: 0xffffffffffbcdeab
Answer: 0x123456ff9abcdeab
(!) Error in index: 4. Output: 0x123456789abcdeff
Answer: 0x12345678ffbcdeab
(!) Error in index: 5. Output: 0x123456789abcffab
Answer: 0x123456789affdeab
(!) Error in index: 6. Output: 0x123456789affdeab
Answer: 0x123456789abcffab
好吧,我考虑过将我的代码更改为带有数组的代码,只是为了获取一个数字 -> 运行 作为数组 -> 更改所需的索引 -> 就是这样。
但是.. 我不能正确地写它所以我坚持移动的东西(我也不能正确地写)。
这是我的尝试:
unsigned long replaceByte(unsigned long original, unsigned char newByte, int indexToReplace){
int size = (sizeof(unsigned long));
char a[size];
for (int i=0; i<size; i++){
if (i=0)
a[0] = original & 0xff;
else
a[i] = original>>(8*i) & 0xff;
}
a[indexToReplace] = newByte;
......// stuck
}
我不允许使用 long long、uint_fast64_t 或 reinterpret_cast 或任何其他“外部”东西。
如果代码在 32 位系统或 64 位系统上 运行ning,我也认为我需要以某种方式进行更改,以确定哪个大小是无符号长(4 或 8 字节)。
本文以 [我的] 热门评论开头。
value
和 mask
需要 unsigned long
.
此外,在进行转换时, 值 are/were 由于表达式提升规则而被截断 [至 32 位]。
在上面,我忘了 value
有同样的问题。
这是强制正确换档的另一种方法:
unsigned long
replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
int shift = indexToReplace*8;
unsigned long value = newByte;
unsigned long mask = 0xff;
value <<= shift;
mask <<= shift;
return (~mask & original) | value;
}
以上是我平时做的。但是,以下 可能 也有效:
unsigned long
replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
int shift = indexToReplace*8;
unsigned long value = ((unsigned long) newByte) >> shift;
unsigned long mask = ((unsigned long) 0xff) >> shift;
return (~mask & original) | value;
}
更新:
hey thanks. The provided codes bring me the following output: 0x12345678cdef34AB instead of 0xAB345678CDEF3456. I'm pretty sure it's related to the little endian thing because it's not a coincidence that instead of the MSB the LSB gets replaced.
它不是字节顺序。这就是 indexToReplace
需要解释的方式。
处理器根据有效的字节序模式获取数据,因此当我们尝试进行移位时,处理器寄存器中的值始终是大字节序[所以,不用担心]
normal/usual是索引从右开始。但是,根据 [correct] 数据,问题希望索引从左开始。
所以,我们只需要调整 index/shift:
unsigned long
replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
#if 0
int shift = indexToReplace * 8;
#else
int shift = ((sizeof(unsigned long) - 1) - indexToReplace) * 8;
#endif
unsigned long value = newByte;
unsigned long mask = 0xff;
value <<= shift;
mask <<= shift;
return (~mask & original) | value;
}
更新#2:
It recognises the "int shift = indexToReplace * 8;" as a comment for some reason, but it still works.
那是因为 #if 0
是 CPP [预处理器] 语句。它的解释方式类似于 #ifdef NEVERWAS
,我们 从不 执行 #define NEVERWAS
,因此包含 #else
下的代码。
您可能希望在编译时使用 -E
and/or -P
选项以查看预处理器阶段的 输出 。
在这种情况下,只有 编译器 会看到的东西是:
int shift = ((sizeof(unsigned long) - 1) - indexToReplace) * 8;
BUT if I try to change the "#if 0" to "#if (is_big_endian == 0)" I get a wrong result when I use "0" as the indexToReplace.
请尽量不要将此称为字节序相关。再一次,这不是而不是正在发生的事情。我发布的代码 不管 处理器字节序模式如何。
请重读有关 correct/proper 解释字节索引的部分。这就是 选择 给字节编号的方式。
再一次,在 99.44% 的情况下,它是从右侧(LSB 到 MSB)定向的。从图形上看,大多数人使用:
| MSB | | | | | | | LSB |
| 01 | 23 | 45 | 67 | 89 | AB | CD | EF | DATA
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | INDEX
但是,对于您的确切问题陈述,它是从左(MSB 到 LSB)方向:
| MSB | | | | | | | LSB |
| 01 | 23 | 45 | 67 | 89 | AB | CD | EF | DATA
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | INDEX
这不寻常。它也较慢,因为移位的计算更复杂。
It gives out: 0x12345678CDEF34FF instead of 0xFF345678CDEF3456
最终,无论您对#if
做了什么,它都选择了不正确的方程。
所以我使用以下代码:
unsigned long replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
int shift = 8 * indexToReplace;
unsigned long value = newByte << shift;
unsigned long mask = 0xff << shift;
return (~mask & original) | value;
}
我用|w|给定了一个词字节。
- 字节的编号从 0(最不重要)到 w/8-1(最重要 显着)。
例如:
replaceByte(unsigned long original, unsigned char newByte, int indexToReplace)
correct answer:
replaceByte(0x12345678CDEF3456, 0xAB, 2) --> 0x1234AB78CDEF3456
(my code's output is: 0x12345678CDAB3456)
correct answer:
replaceByte(0x12345678CDEF3456, 0xAB, 0) --> 0xAB345678CDEF3456
(my code's output is: 0x12345678cdef34AB)
我认为我需要检查系统是大端还是小端,因为我的代码更改了完全相反的字节。比方说它改变了 MSB 而不是 LSB。 但是...我意识到这并不重要,因为我正在使用位。
如你所见,这里的代码改错了索引:
(!) Error in index: 0. Output: 0x123456789abcdeff
Answer: 0xff3456789abcdeab
(!) Error in index: 1. Output: 0x123456789abcffab
Answer: 0x12ff56789abcdeab
(!) Error in index: 2. Output: 0x123456789affdeab
Answer: 0x1234ff789abcdeab
(!) Error in index: 3. Output: 0xffffffffffbcdeab
Answer: 0x123456ff9abcdeab
(!) Error in index: 4. Output: 0x123456789abcdeff
Answer: 0x12345678ffbcdeab
(!) Error in index: 5. Output: 0x123456789abcffab
Answer: 0x123456789affdeab
(!) Error in index: 6. Output: 0x123456789affdeab
Answer: 0x123456789abcffab
好吧,我考虑过将我的代码更改为带有数组的代码,只是为了获取一个数字 -> 运行 作为数组 -> 更改所需的索引 -> 就是这样。 但是.. 我不能正确地写它所以我坚持移动的东西(我也不能正确地写)。 这是我的尝试:
unsigned long replaceByte(unsigned long original, unsigned char newByte, int indexToReplace){
int size = (sizeof(unsigned long));
char a[size];
for (int i=0; i<size; i++){
if (i=0)
a[0] = original & 0xff;
else
a[i] = original>>(8*i) & 0xff;
}
a[indexToReplace] = newByte;
......// stuck
}
我不允许使用 long long、uint_fast64_t 或 reinterpret_cast 或任何其他“外部”东西。
如果代码在 32 位系统或 64 位系统上 运行ning,我也认为我需要以某种方式进行更改,以确定哪个大小是无符号长(4 或 8 字节)。
本文以 [我的] 热门评论开头。
value
和 mask
需要 unsigned long
.
此外,在进行转换时, 值 are/were 由于表达式提升规则而被截断 [至 32 位]。
在上面,我忘了 value
有同样的问题。
这是强制正确换档的另一种方法:
unsigned long
replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
int shift = indexToReplace*8;
unsigned long value = newByte;
unsigned long mask = 0xff;
value <<= shift;
mask <<= shift;
return (~mask & original) | value;
}
以上是我平时做的。但是,以下 可能 也有效:
unsigned long
replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
int shift = indexToReplace*8;
unsigned long value = ((unsigned long) newByte) >> shift;
unsigned long mask = ((unsigned long) 0xff) >> shift;
return (~mask & original) | value;
}
更新:
hey thanks. The provided codes bring me the following output: 0x12345678cdef34AB instead of 0xAB345678CDEF3456. I'm pretty sure it's related to the little endian thing because it's not a coincidence that instead of the MSB the LSB gets replaced.
它不是字节顺序。这就是 indexToReplace
需要解释的方式。
处理器根据有效的字节序模式获取数据,因此当我们尝试进行移位时,处理器寄存器中的值始终是大字节序[所以,不用担心]
normal/usual是索引从右开始。但是,根据 [correct] 数据,问题希望索引从左开始。
所以,我们只需要调整 index/shift:
unsigned long
replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
#if 0
int shift = indexToReplace * 8;
#else
int shift = ((sizeof(unsigned long) - 1) - indexToReplace) * 8;
#endif
unsigned long value = newByte;
unsigned long mask = 0xff;
value <<= shift;
mask <<= shift;
return (~mask & original) | value;
}
更新#2:
It recognises the "int shift = indexToReplace * 8;" as a comment for some reason, but it still works.
那是因为 #if 0
是 CPP [预处理器] 语句。它的解释方式类似于 #ifdef NEVERWAS
,我们 从不 执行 #define NEVERWAS
,因此包含 #else
下的代码。
您可能希望在编译时使用 -E
and/or -P
选项以查看预处理器阶段的 输出 。
在这种情况下,只有 编译器 会看到的东西是:
int shift = ((sizeof(unsigned long) - 1) - indexToReplace) * 8;
BUT if I try to change the "#if 0" to "#if (is_big_endian == 0)" I get a wrong result when I use "0" as the indexToReplace.
请尽量不要将此称为字节序相关。再一次,这不是而不是正在发生的事情。我发布的代码 不管 处理器字节序模式如何。
请重读有关 correct/proper 解释字节索引的部分。这就是 选择 给字节编号的方式。
再一次,在 99.44% 的情况下,它是从右侧(LSB 到 MSB)定向的。从图形上看,大多数人使用:
| MSB | | | | | | | LSB |
| 01 | 23 | 45 | 67 | 89 | AB | CD | EF | DATA
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | INDEX
但是,对于您的确切问题陈述,它是从左(MSB 到 LSB)方向:
| MSB | | | | | | | LSB |
| 01 | 23 | 45 | 67 | 89 | AB | CD | EF | DATA
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | INDEX
这不寻常。它也较慢,因为移位的计算更复杂。
It gives out: 0x12345678CDEF34FF instead of 0xFF345678CDEF3456
最终,无论您对#if
做了什么,它都选择了不正确的方程。