如何将结构体数组指针传入函数?代码错误排查
问题排查与代码修复方案
核心错误点分析
指针类型不匹配与赋值错误
ptr = &weapon_list;:数组名weapon_list本身就是指向数组首元素的指针(类型为struct machine_gun*),&weapon_list是指向整个数组的指针(类型为struct machine_gun (*)[2]),赋值给struct machine_gun*类型的ptr会导致类型不兼容。正确写法是ptr = weapon_list;,甚至可以直接省略ptr,直接使用weapon_list作为指针。battle(&ptr);:battle函数的参数是struct machine_gun*,但这里传递的是指针的地址(struct machine_gun**),类型完全不匹配,导致函数内的指针操作全部错误。正确调用应为battle(ptr);或battle(weapon_list);。
结构体成员访问符号错误
函数battle中,wpn是struct machine_gun*类型,wpn[i]等价于*(wpn + i),是一个结构体实例而非指针,因此访问成员应该用.而非->。比如wpn[i]->name要改成wpn[i].name,wpn[i]->rounds改成wpn[i].rounds,以此类推。变量作用域与未初始化问题
在if(choice == 1)和else块中,重新定义了enum states state,这是块级局部变量,不会影响外部的state变量,导致后续switch中使用的state是未初始化的垃圾值。正确写法是直接给外部的state赋值:if(choice == 1){ state = Ya; } else{ state = Tidak; }Switch Case 缺少Break语句
switch(state)中,case Tidak执行后没有break,会继续执行case Ya的代码,导致逻辑错误,需要在每个case末尾添加break;或直接用return终止函数。typedef并非问题根源
你怀疑的typedef不是错误原因,typedef只是简化结构体类型的书写,不影响指针的本质操作,当前代码不需要typedef也能正常运行。
修正后的完整代码
#include <stdio.h> struct machine_gun{ char name[10]; int rounds; int damage; }; enum states{ Tidak, Ya }; void battle(struct machine_gun* wpn); int main(){ struct machine_gun weapon_list[2] = { {"Holger", 400, 20}, {"M4LMG", 320, 25} }; int choice; printf("Boss has appeared! Enter 1 to fight the boss, 0 to run\n"); scanf("%d", &choice); if(choice == 1){ battle(weapon_list); } else{ printf("You ran away."); } return 0; } void battle (struct machine_gun* wpn){ int choice; int weapon_choice; int boss_hp = 1000; enum states state; printf("###Weapon Lists###\n"); for(int i = 0; i < 2; i++){ printf("Name: %s\n", wpn[i].name); printf(" Rounds: %d\n", wpn[i].rounds); printf(" Damage: %d\n", wpn[i].damage); } printf("\nBoss HP is 1000, are you sure you want to fight?\n1. Yes\n2. No\n"); scanf("%d", &choice); if(choice == 1){ state = Ya; } else{ state = Tidak; } switch(state){ case Tidak: printf("Game Over!\nYou've been killed by the Boss."); return; case Ya: printf("Choose your weapon!\n"); printf("1. %s with %d ammo and does %d damage\n", wpn[0].name, wpn[0].rounds, wpn[0].damage); printf("2. %s with %d ammo and does %d damage\n", wpn[1].name, wpn[1].rounds, wpn[1].damage); scanf("%d", &weapon_choice); break; } if(weapon_choice == 1){ int bullets_used = boss_hp / wpn[0].damage; if(boss_hp % wpn[0].damage != 0){ bullets_used += 1; } if(wpn[0].rounds >= bullets_used){ wpn[0].rounds -= bullets_used; printf("You shot the boss with %d bullets\nCongratulation! You killed the boss, thanks for playing!\n", bullets_used); printf("Your ammo remains: %d", wpn[0].rounds); } else { printf("Not enough ammo! You were killed by the Boss."); } } else if(weapon_choice == 2){ int bullets_used = boss_hp / wpn[1].damage; if(boss_hp % wpn[1].damage != 0){ bullets_used += 1; } if(wpn[1].rounds >= bullets_used){ wpn[1].rounds -= bullets_used; printf("You shot the boss with %d bullets\nCongratulation! You killed the boss, thanks for playing!\n", bullets_used); printf("Your ammo remains: %d", wpn[1].rounds); } else { printf("Not enough ammo! You were killed by the Boss."); } } else { printf("Invalid weapon choice! You were killed by the Boss."); } }
额外优化说明
- 补充了
main函数的return 0;,符合C语言标准。 - 增加了弹药不足、无效选择的容错逻辑,避免程序出现不合理输出。
- 修复了伤害计算的边界问题(当boss hp无法被武器伤害整除时,需要多打一枪)。
内容的提问来源于stack exchange,提问作者MJee
相关产品推荐
相关产品推荐

