我正在学习C ++,而且我正在学习“在C ++中思考”这本书,我正在练习,我无法理解为什么在这个练习中:
定义
int
数组。获取该数组的起始地址,并使用static_cast
将其转换为void*
。编写一个函数,它接受void*
,一个数字(表示一个字节数)和一个值(表示每个字节应该设置的值)作为参数。该函数应将指定范围内的每个字节设置为指定值。尝试使用int
数组上的函数。
此解决方案有效
#include<iostream>
using namespace std;
#define PR(EX) cout << #EX << ": " << EX << endl;
void f1( void* v, size_t num_bytes, int val){
unsigned char* p_addr = reinterpret_cast<unsigned char*>(v);
unsigned char byte = static_cast<unsigned char>(val);
for( size_t i = 0; i < num_bytes; i++){
*p_addr = byte++;
p_addr++;
}
PR(num_bytes);
}
int main(){
int a[5] = { 0, 0, 0, 0, 0 };
int value = 67;
void* vp = static_cast<void*>(&a);
f1(vp, sizeof(a), value);
unsigned char* byte = reinterpret_cast<unsigned char*>(vp);
for( int i = 0; i < sizeof(a) / sizeof(a[0]); i++){
cout << "a[" << i << "] = ";
for( int j = 0; j < sizeof(int); j++){
cout << reinterpret_cast<int*>(*byte) << " ";
byte++;
}
cout << endl;
}
return 0;
}
虽然这个没有
#include<iostream>
using namespace std;
#define PR(EX) cout << #EX << ": " << EX << endl;
void f1( void* v, size_t num_bytes, int val){
unsigned char* p_addr = reinterpret_cast<unsigned char*>(v);
unsigned char byte = static_cast<unsigned char>(val);
for( size_t i = 0; i < num_bytes; i++){
*p_addr = byte++;
p_addr++;
}
PR(num_bytes);
}
int main(){
int a[5] = { 0, 0, 0, 0, 0 };
int value = 67;
void* vp = static_cast<void*>(&a);
unsigned char* byte = reinterpret_cast<unsigned char*>(vp);
for( size_t i = 0; i < (sizeof(a) / sizeof(a[0])); i++){
cout << "a[" << i << "] = ";
for( size_t j = 0; j < sizeof(int); j++){
cout << *byte;
byte++;
}
cout << endl;
}
PR(*byte);
f1(vp, sizeof(a), value);
for( int i = 0; i < sizeof(a) / sizeof(a[0]); i++){
cout << "a[" << i << "] = ";
for( int j = 0; j < sizeof(int); j++){
cout << reinterpret_cast<int*>(*byte) << " ";
byte++;
}
cout << endl;
}
return 0;
}
差异在于我定义指针byte
的位置,在函数调用之前的“工作”版本中,而在之前的“不工作”版本中。这两个版本的cout
是
a[0] =
a[1] =
a[2] =
a[3] =
a[4] =
*byte:
num_bytes: 20
a[0] = 0 0 0 0
a[1] = 0x3b 0x8 0x40 0
a[2] = 0 0 0 0
a[3] = 0x4 0 0 0
a[4] = 0 0 0 0
和
num_bytes: 20
a[0] = 0x43 0x44 0x45 0x46
a[1] = 0x47 0x48 0x49 0x4a
a[2] = 0x4b 0x4c 0x4d 0x4e
a[3] = 0x4f 0x50 0x51 0x52
a[4] = 0x53 0x54 0x55 0x56
在第二个中我的字节正在以正确的方式改变,而在第一个中,在我看来,某些事情出错了。显然问题在于我定义byte
指针的位置,因为我是初学者并且自己学习,所以我希望理解我的错误。
好的,我已经理解了我的错误,感谢您的建议,我修改了代码,现在它打印出我期待的内容
#include<iostream>
using namespace std;
#define PR(EX) cout << #EX << ": " << EX << endl;
void f1( void* v, size_t num_bytes, int val){
unsigned char* p_addr = reinterpret_cast<unsigned char*>(v);
unsigned char byte = static_cast<unsigned char>(val);
for( size_t i = 0; i < num_bytes; i++){
*p_addr = byte++;
p_addr++;
}
PR(num_bytes);
}
int main(){
int a[5] = { 0, 0, 0, 0, 0 };
int value = 67;
void* vp = static_cast<void*>(a);
unsigned char* byte = reinterpret_cast<unsigned char*>(vp);
for( size_t i = 0; i < (sizeof(a) / sizeof(a[0])); i++){
cout << "a[" << i << "] = ";
for( size_t j = 0; j < sizeof(int); j++){
cout << reinterpret_cast<int*>(*byte);
byte++;
}
cout << endl;
}
byte = reinterpret_cast<unsigned char*>(vp);
f1(vp, sizeof(a), value);
for( int i = 0; i < sizeof(a) / sizeof(a[0]); i++){
cout << "a[" << i << "] = ";
for( int j = 0; j < sizeof(int); j++){
cout << *byte << " ";
byte++;
}
cout << endl;
}
return 0;
}
a[0] = 0000
a[1] = 0000
a[2] = 0000
a[3] = 0000
a[4] = 0000
num_bytes: 20
a[0] = C D E F
a[1] = G H I J
a[2] = K L M N
a[3] = O P Q R
a[4] = S T U V
答案 0 :(得分:0)
您正在使用指针来打印数组值,并且您的打印循环会使指针前进。 在您的第二个代码清单中,您无法将指针重置为数组的开头。您的第二个循环将打印出超出数组末尾的值。
编辑:
在第一个循环中,您正在打印*byte
,它被解释为8位字符值。该数组初始化为所有不是可打印ASCII值的零。如果要打印数值,请将*byte
更改为static_cast<int>(*byte)
。
在第二个循环中,reinterpret_cast<int*>(*byte)
尝试将unsigned char重新解释为指向int的指针。我不认为这就是你的意思。您应该像第一个循环一样将其更改为static_cast<int>(*byte)
。或者,因为您的函数已使用有效的ASCII字符代码填充数组,所以第二个循环可以将*byte
发送到cout。
我可以看到我对代码和输出的更改here