C语言指针实现扫雷打印地图触发指针类型比较警告求助
问题说明
基于C语言指针开发扫雷游戏,已完成initialmap(地图初始化)、Printmap(地图打印)两个功能函数,编译时抛出如下警告:
[Warning] comparison of distinct pointer types lacks a cast
原实现代码如下:
#include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX_ROW 5 #define MAX_COL 5 void initialmap(char *Minemap[][7],char *Playermap[][7]){ //playermap int row,col; for(row=1;row<MAX_ROW+1;row++){ for(col=1;col<MAX_COL+1;col++){ *(Playermap+row)+col=="*"; } } //minemap for(row=1;row<=MAX_ROW-1;row++){ for(col=1;col<=MAX_COL-1;col++){ (*(Minemap+row)+col)=="0"; } } //place mines int i; for(i=1;i<=5;i++){ int minerow=rand() % (5-1+1)+1; int minecol=rand() % (5-1+1)+1; if((*(Minemap+minerow)+minecol)=="0") (*(Minemap+minerow)+minecol)=="1" ; } } void Printmap(char *Playermap[7][7]) { int row,col; printf(" 0 1 2 3 4 \n"); printf(" - - - - -\n"); for(row=1;row<6;row++){ printf("%d|",row-1); for(col=1;col<6;col++){ printf("%c ",(*(Playermap+row)+col)); } printf("\n"); } }
问题定位
代码存在多处基础语法和逻辑错误,直接触发类型不匹配警告的点和其他关联问题如下:
- 函数参数类型定义错误:扫雷地图是存储
'*'/'0'/'1'这类字符的二维数组,但参数写成了char *Minemap[][7],这是元素为char*指针的二维数组,和实际需要的存储结构完全不符。正确的字符二维数组传参类型应为char Minemap[][7]。 - 运算符混淆:所有需要给数组元素赋值的位置都误用了
==(相等比较运算符),而非=(赋值运算符),这些语句只会做无意义的比较,不会修改数组内的任何值。 - 指针解引用层级不足:访问二维数组元素时,
*(Playermap+row)+col等价于Playermap[row] + col,拿到的是第row行第col列元素的内存地址(char*类型指针),不是元素本身。要拿到元素值需要二次解引用,正确指针写法为*(*(Playermap + row) + col),等价于数组下标写法Playermap[row][col]。 - 字符/字符串常量混淆:C语言中单引号
''包裹的是char类型字符,双引号""包裹的是字符串常量(本质是const char*类型指针,指向字符串首地址)。代码中所有"*"/"0"/"1"都是字符串指针,拿指针和指针做类型不匹配的比较,直接触发本次警告。 - 初始化范围错误:雷区地图初始化只遍历到
MAX_ROW-1、MAX_COL-1,5*5的游玩区域最后一行、最后一列完全没有初始化,是随机脏值。 - 埋雷逻辑漏洞:埋雷循环固定跑5次,没有判断目标位置是否已经埋雷,随机到重复位置时会出现雷数不足5个的问题;同时漏了随机数种子初始化,每次运行程序埋雷位置完全固定。
- 打印逻辑错误:打印时传入的是元素的内存地址而非字符值,用
%c格式打印会输出乱码。
修正后可运行代码
#include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX_ROW 5 #define MAX_COL 5 // 数组多开2个长度留边界,避免排查周围雷数时数组越界 void initialmap(char Minemap[][7], char Playermap[][7]){ int row, col; // 初始化玩家可见地图 for(row = 1; row <= MAX_ROW; row++){ for(col = 1; col <= MAX_COL; col++){ *(*(Playermap + row) + col) = '*'; } } // 初始化雷区地图 for(row = 1; row <= MAX_ROW; row++){ for(col = 1; col <= MAX_COL; col++){ *(*(Minemap + row) + col) = '0'; } } // 初始化随机数种子 srand((unsigned int)time(NULL)); // 埋5个雷,去重 int mine_count = 0; while(mine_count < 5){ int minerow = rand() % MAX_ROW + 1; int minecol = rand() % MAX_COL + 1; if(*(*(Minemap + minerow) + minecol) == '0'){ *(*(Minemap + minerow) + minecol) = '1'; mine_count++; } } } void Printmap(char Playermap[][7]) { int row, col; printf(" 0 1 2 3 4 \n"); printf(" - - - - -\n"); for(row = 1; row <= MAX_ROW; row++){ printf("%d|", row-1); for(col = 1; col <= MAX_COL; col++){ printf("%c ", *(*(Playermap + row) + col)); } printf("\n"); } } int main(){ char mine_map[7][7] = {0}; char player_map[7][7] = {0}; initialmap(mine_map, player_map); Printmap(player_map); return 0; }
内容的提问来源于stack exchange,提问作者Kevin Chen
相关产品推荐
相关产品推荐

