You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用指针遍历Viewer数组遇空指针,如何正确迭代?

问题:C语言指针遍历Viewer数组时第二次迭代指针为空的原因及修复

我用C写了个统计指定视频观看次数的代码,想用指针遍历Viewer数组,但第一次迭代正常,第二次迭代时ptr指针就指向空了。不确定ptr++是不是适合这种场景,想知道正确的数组迭代方式。代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h> // 后续用strcmp需要加这个头文件

typedef struct Video {
    char *name;
    int unique_views;
} Video;

typedef struct Viewer {
    char *username;
    Video *watched_videos;
    int watched_videos_size;
} Viewer;

int count_views(Viewer **viewers, int viewers_size, char *video_name)
{
    Viewer *ptr;
    Video *vid;
    int count=0;
    ptr = *viewers;
    for (int i=0;i< viewers_size;i++){
        printf("%s ",ptr->username);
        vid=ptr->watched_videos;
        for (int j=0;j < ptr->watched_videos_size;j++){
            printf("%d %d",j,ptr->watched_videos_size);
            printf("%s\n",vid->name);
            if (vid->name == video_name){
                count++; 
            }
            vid++;
        }
        ptr++;
    }
    return count;
}

int main()
{
    Video videos[] = { {.name = "Soccer", .unique_views = 500},
                       {.name = "Basketball", .unique_views = 1000} };
                       
    Video videos2[] = { {.name = "Soccer", .unique_views = 500} };
    
    Viewer viewer = {.username = "Dave", .watched_videos = videos,
                     .watched_videos_size = 2} ;
    
    Viewer view = {.username = "Bob", .watched_videos = videos2,
                     .watched_videos_size = 1};
    
    Viewer *viewers[] = { &viewer, &view };
    printf("%d", count_views(viewers, 2, "Soccer")); /* should print 1 */
}

核心问题分析

你的ptr++之所以失效,是因为**viewers是一个Viewer*类型的指针数组**,而非连续的Viewer结构体数组:

  • main里定义的Viewer *viewers[] = { &viewer, &view };,存的是两个指向独立Viewer结构体的指针,这两个指针的内存地址并不连续(viewer和view是栈上的两个独立变量,地址无连续性)。
  • 当你执行ptr = *viewers拿到第一个指针后,ptr++会把指针地址增加sizeof(Viewer),但这个新地址并不是第二个Viewer*的地址,而是跑到了无效内存区域,导致第二次迭代时ptr指向空或垃圾值。

正确的迭代方式

写法1:下标访问指针数组(最直观)

直接通过viewers[i]获取每个Viewer*,避免指针操作出错:

int count_views(Viewer **viewers, int viewers_size, char *video_name)
{
    Video *vid;
    int count=0;
    for (int i=0;i< viewers_size;i++){
        Viewer *ptr = viewers[i]; // 直接取数组内的指针
        printf("%s ",ptr->username);
        vid=ptr->watched_videos;
        for (int j=0;j < ptr->watched_videos_size;j++){
            printf("%d %d ",j,ptr->watched_videos_size);
            printf("%s\n",vid->name);
            // 字符串比较用strcmp,而非==
            if (strcmp(vid->name, video_name) == 0){
                count++; 
            }
            vid++;
        }
    }
    return count;
}

写法2:二级指针遍历指针数组

如果坚持用指针遍历,直接操作传入的二级指针viewers:

int count_views(Viewer **viewers, int viewers_size, char *video_name)
{
    Video *vid;
    int count=0;
    Viewer **ptr = viewers; // 二级指针指向指针数组起始
    for (int i=0;i< viewers_size;i++){
        Viewer *current_viewer = *ptr; // 取出当前Viewer指针
        printf("%s ",current_viewer->username);
        vid=current_viewer->watched_videos;
        for (int j=0;j < current_viewer->watched_videos_size;j++){
            printf("%d %d ",j,current_viewer->watched_videos_size);
            printf("%s\n",vid->name);
            if (strcmp(vid->name, video_name) == 0){
                count++; 
            }
            vid++;
        }
        ptr++; // 二级指针++,指向数组内下一个Viewer*
    }
    return count;
}

额外修复点

  1. 字符串比较错误:原代码用vid->name == video_name是比较指针地址,而非字符串内容,必须用strcmp函数(需包含<string.h>)。
  2. 头文件错误:C语言用#include而非#import,后者是Objective-C语法。
  3. printf格式问题:原代码换行符位置错误,改为printf("%s\n",vid->name);。

内容的提问来源于stack exchange,提问作者Anshal Antony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:55:37