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

C++中如何正确使用struct?为何Player、Screen赋值的@未正常显示

显示异常的核心原因

你在(1,1)位置写入的玩家@无法显示,本质是不同函数中创建的struct实例是完全独立的内存块,没有任何关联:

  • main()函数里创建了局部的Player p和Screen s,并且在这个s的(1,1)位置写入了玩家符号@
  • 但调用draw()函数时,函数内部又在自己的栈空间里重新创建了全新的Screen s和Player player对象:这个新的Screen对象的地图是默认初始化的状态,(1,1)位置还是原本的.字符,和main函数里被修改过的s没有任何关系;同理这里新建的player对象也是独立的,health是默认值100,和main里每轮自减的p完全无关。
    简单说:你修改的是A对象的内容,但绘制的时候读的是B对象的内容,自然看不到修改效果。

C++中struct的正确使用规范

结合这个终端小游戏的开发场景,你需要注意几个struct的使用要点:

  1. 头文件定义的合规性
    • 你目前用头文件守卫(#ifndef/#define/#endif)避免重复包含的写法是正确的;struct成员带默认值初始化(比如int health = 100;)是C++11支持的合法语法,没有问题。
    • 注意不要在头文件中直接定义struct的全局实例,否则多个cpp文件包含该头文件时会触发重复定义的链接错误,你现在只在头文件里定义struct类型、不定义全局实例的写法是合规的。
  2. 跨函数传递struct实例的正确方式
    • struct是值类型,默认创建的实例都是独立的内存块,不同作用域下同名的struct变量没有任何共享状态。如果需要在其他函数中读取或修改原struct的内容,必须通过引用或指针把原实例传入函数,绝对不能在函数内部自行创建新的副本。
    • 对你当前的draw()函数,正确的写法是接收已存在对象的引用,而不是在函数内部新建:
      // 用const引用传递:没有大数组的拷贝开销,同时保证函数内不会意外修改原数据
      int draw(const Screen& gameMap, const Player& gamePlayer) {
          // 循环边界和实际初始化的地图行数匹配,避免数组越界
          for(int i = 0; i < 19; i++) {
              cout << gameMap.screen[i] << endl;
          }
          cout << "HP: " << gamePlayer.health << endl;
          return 0;
      }
      
      在main函数中调用时直接传入已创建好的实例即可:
      // main函数内部逻辑
      Player p;
      Screen s;
      s.screen[p.y][p.x] = p.symbol;
      draw(s, p); // 把原对象的引用传入绘制函数
      
  3. 语法细节优化
    • C中定义struct类型的变量时,不需要像C语言那样在类型前加struct关键字,直接写Player p;、Screen s;即可——C语言的兼容写法是合法的,但不属于C的常规写法。

其他需要注意的细节

  • 你声明的Screen是21行的二维数组,但实际初始化时只写了19行字符串,剩下的两行是未初始化的空字符,会导致绘制时出现乱码,需要按照数组大小补全初始化内容,同时对应修改绘制时的循环边界,避免数组越界。
  • 目前的逻辑每轮循环只在玩家新位置写入@,但没有把上一轮的玩家位置重置为.,运行一段时间后地图上会留下一串连续的@标记,后续可以在玩家移动后增加位置重置的逻辑。

内容的提问来源于stack exchange,提问作者Gavin C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 23:45:00