这段代码有什么作用? (关于指针)

时间:2017-01-16 13:07:02

标签: c++ pointers

我有这个代码并且我停留在第二行

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;这条线是什么意思?

2 个答案:

答案 0 :(得分:2)

  

int * ip =(int *)p;这条线是什么意思?

这意味着,&#34;创建一个指向整数的指针,这些整数从与p相同的地址开始。&#34;

该函数期望p指向表示5个整数的字节序列。

只有在p被强制转换为 const char*之前指向一个整数序列时,才会定义此函数的行为

在实践中,此代码的作者假设:

  1. 字节序列的编码方式使它们真正代表了这台机器上的5个整数(考虑到字体大小和架构的字节顺序)。

  2. p表示的地址对齐对于将存储器作为整数寻址是正确的(某些处理器在这方面有限制)。

  3. 除了作为警示故事之外,它可能不是您想要复制或学习的代码。

答案 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元素添加到resip实际上可能指向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;
}