C#报CS0165编译错误:使用未赋值局部变量'h'如何解决
C# 编译错误 CS0165: 使用了未赋值的局部变量 'h' 解决方案
报错根因
这个错误是C#编译器的确定性赋值检查机制触发的:C#要求所有局部变量在被读取取值前,必须在所有可达代码路径上完成显式赋值,编译器不会通过静态分析推断循环、条件分支执行后变量的实际值。
你的代码里变量i和h仅在for循环的初始化块中被赋值,编译器会判定「如果循环条件初始就不满足、一次都不执行,两个变量就始终是未赋值状态」,因此读取m[i,h]的操作直接触发编译报错。
另外这段代码还藏了一个运行时bug:8*8的二维数组合法索引范围是0~7,双层循环正常退出时i=8、h=8,就算绕过编译检查,执行到输出语句时也会抛出索引越界异常。
修复方法
根据你的代码意图,两种改法都可以:
写法1(推荐):循环变量作用域限制在循环内部,直接用合法索引访问目标元素
如果你的目的是输出数组最后一个元素,不需要把循环计数变量声明在循环外,从根源上避免变量作用域和赋值问题:
static void Main() { int[ , ] m = new int [8,8]; Random rnd = new Random(); // 循环变量i、h直接在for语句内声明,作用域仅限循环内部 for(int i = 0 ; i< 8 ; i++) { for(int h = 0 ; h< 8 ; h++) { m[i,h] = rnd.Next(10); } } // 直接访问最后一个元素的合法索引(7,7) Console.WriteLine(m[7,7]); }
写法2:必须在循环外使用计数变量时,声明时赋初始值
如果你确实需要在循环结束后拿到i、h的值,声明变量时给一个初始值就能通过编译检查,同时要修正索引越界问题:
static void Main() { int[ , ] m = new int [8,8]; // 声明时显式给初始值,满足编译器确定性赋值要求 int i = 0; int h = 0; Random rnd = new Random(); for( i = 0 ; i< 8 ; i++) { for( h = 0 ; h< 8 ; h++) { m[i,h] = rnd.Next(10); } } // 循环结束后i、h的值都是8,减1后才是合法的最后一个元素索引 Console.WriteLine(m[i-1,h-1]); }
编码建议
- 循环计数变量优先在for语句内部声明,缩小变量作用域能减少很多无意义的编译错误和逻辑bug
- 访问数组元素时永远记得校验索引范围,不要依赖循环退出时的变量值计算索引,很容易出现越界问题
内容的提问来源于stack exchange,提问作者umut
相关产品推荐
相关产品推荐

