Wabi_sabi_x 2024-01-07 16:17 采纳率: 50%
浏览 5

不同数据类型的指针的比较

操作环境:vs2022 C++;
现象:我从文本文件分块读取数据,顺序查找关键字时, 其中要检查指针rec1是否越界(上界为buffer+ReadLength)
注: 各自定义

img

img

1.当如下写时:

img

会发生:每十次循环,就会跳出循环!但应当循环ReadLength,才跳出才对。

img

2.当如下写时:

img

会发生:正常循环 ReadLength次

img

问题:虽然函数的功能完成了,但我不理解为什么?第一种写法是会出错!请大神教教!-!

详细原码如下:(其中由一部分是为了观察写的)

//分块顺序查找
int SeqSearch(FILE* SourceFile, char* k)
{
    char* buffer = (char*)malloc(BufferSize);
    // 检查内存分配是否成功
    if (buffer == NULL) {
        cout << "内存分配失败的处理" << endl;
        exit(2);
    }
    fseek(SourceFile, 0L, SEEK_SET);// 将文件指针移动到文件开头
    size_t ReadLength;
    record* rec1;
    int i = 0;
    while (ReadLength = fread(buffer, RecordSize, RecordCount, SourceFile))// 从文件中读取 RecordSize*RecordCount的数据到缓冲区,失败返回0,成功则返回实际读取到的文件内容的块数。
    {
        rec1 = (record*)buffer;
        cout << "域外之地\n";
        while ((char*)rec1 < (buffer + ReadLength) && _strnicmp((char*)k, (char*)rec1, 10) != 0)//比较两个字符串中指定数目10前的字符(不考虑大小写)。
        {
            //(char*)rec1 < (buffer + ReadLength) 此时每十次循环,就会跳出循环!
            //rec1 <(record*) buffer + ReadLength  这样写就是正常循环 ReadLength次
            if (i < 2000)
            {
                cout << i << ":";
                printf("%.10s  %.20s  %p  %p  %d", (char*)k, (char*)rec1, rec1, buffer,ReadLength);
                cout << endl;
            }

            rec1++;
            i++;
        }
        if (_strnicmp((char*)k, (char*)rec1, 10) == 0)
        {
            printf("查找成功:\n%.100s", (char*)rec1);
            free(buffer);
            return i;
        }
    }
  
    return -1;
}

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2024-01-07 18:13
    关注

    【以下回答由 GPT 生成】

    #include <stdio.h>
    
    int main() {
        int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
        // 第一种写法
        char *p = (char *)array;
        int i;
        for (i = 0; i < 10; i++) {
            if (*((int *)p) == 5) {
                break;
            }
            p += sizeof(int);
        }
    
        // 第二种写法
        int *q = array;
        int j;
        for (j = 0; j < 10; j++) {
            if (*q == 5) {
                break;
            }
            q++;
        }
    
        return 0;
    }
    

    答案:

    第一种写法会出错的原因是:

    在第一种写法中,将整型数组array转换为char类型指针p后,每次移动指针p的位置时,移动的步长是整型的大小(sizeof(int))。然后通过对p指向的内存地址解引用,获取该位置上的值。

    但是在循环条件中,是判断p指向的内存地址上的值是否等于5。由于int类型占用的字节数通常大于char类型,所以移动p指针时只移动了char类型大小的步长,导致每次解引用p指针时获取的值不是整型数组array中的值,因此循环无法正常按照预期退出。

    改正第一种写法,可以将循环条件中的比较改为比较p指向的内存地址上的前后四个字节是否等于5:

    // 第一种写法
    char *p = (char *)array;
    int i;
    for (i = 0; i < 10; i++) {
        if (*(int *)p == 5) {
            break;
        }
        p += sizeof(int);
    }
    

    第二种写法是正常循环 ReadLength 次,因为将整型数组array转换为int类型指针q后,每次移动指针q的位置时,移动的步长是整型的大小(sizeof(int))。然后通过对q指向的内存地址解引用,获取该位置上的值。

    所以第二种写法是正确的。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 1月7日

悬赏问题

  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Linux权限管理相关操作(求解答)
  • ¥15 Bug traq 数据包 大概什么价
  • ¥15 在anaconda上pytorch和paddle paddle下载报错
  • ¥25 自动填写QQ腾讯文档收集表
  • ¥15 DbVisualizer Pro 12.0.7 sql commander光标错位 显示位置与实际不符
  • ¥15 android 打包报错
  • ¥15 关于stm32的问题
  • ¥15 ncode振动疲劳分析中,noisefloor如何影响PSD函数?