我有这个代码并且我停留在第二行
unsigned long check_password(const char* p){
int* ip = (int*)p;
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i];
}
return res;
}
int* ip = (int*)p;
这条线是什么意思?
答案 0 :(得分:2)
int * ip =(int *)p;这条线是什么意思?
这意味着,&#34;创建一个指向整数的指针,这些整数从与p相同的地址开始。&#34;
该函数期望p指向表示5个整数的字节序列。
只有在p被强制转换为 const char*
之前指向一个整数序列时,才会定义此函数的行为
在实践中,此代码的作者假设:
字节序列的编码方式使它们真正代表了这台机器上的5个整数(考虑到字体大小和架构的字节顺序)。
p表示的地址对齐对于将存储器作为整数寻址是正确的(某些处理器在这方面有限制)。
除了作为警示故事之外,它可能不是您想要复制或学习的代码。
答案 1 :(得分:1)
unsigned long check_password(const char* p){
int* ip = (int*)p; // line 2, non-const not required
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i]; // line 6
}
return res;
}
第2行将ip
声明为指向整数的指针,并将其初始化为(int*)p
。 (int*)p
是一个C风格的强制转换,在这种情况下解析为reinterpret_cast<int*>(const_cast<char*>(p))
。见
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
ip
现在指向p的内存位置。使用ip
时,该位置的内存被解释为持有一个整数,即使它包含一个char;并且它可以被修改,即使它最初被声明为const。
第6行将ip
视为指向int
数组的第一个元素,并将该数组的i
元素添加到res
。 ip
实际上可能指向char
数组的第一个元素。这意味着,该数组的每个迭代sizeof(int)
个连续元素都被解释为单个int
的表示。
这段代码的意图可能是,5 int
s的序列作为char
长度为sizeof(int)*5
的数组传递。
请注意,如果p
实际上并未指向大小至少为sizeof(int)*5
的内存,则此代码为UB,因为该区域中的内存已被读取。即char
- 数组的长度必须至少为sizeof(int)*5
。
不需要在代码中删除const
unsigned long check_password(const char* p){
const int* ip = reinterpret_cast<const int*>(p);
int res = 0;
for (int i = 0; i < 5; ++i){
res += ip[i];
}
return res;
}