Unity面试和总结分析(三)——几个简单却容易被忽视的坑

有人说编程就是一个踩坑的过程,踩过的坑越多,会的就越多,能力也会越来越完善,我觉得是有一定道理的。
在这段时间的面试里,就遇到了一些很低级却可能注意不到的坑,以下用面试题的形式逐题来分析一下。
注意,在这种题目中,不要在意语法问题,多数情况可能会使用伪代码编写。


1.unit类型的使用

有如下一段代码,运行后会发生什么:
    for(uint i=10;i>=0;i--)
        Debug.Log(i.ToString()); 
  • 分析
    这是一个最常见的for循环,与普通的int型下标不同的是,i是uint型的。uint型有一个特点,它不能为负,当它为0的时候如果再次减小,会导致数据溢出,得到最大的值。
      uint i = 0;
      i--;
      Console.WriteLine(i.ToString());//输出 4294967295

再回到最初的循环,这个循环的进入条件是i>=0,对于一个uint型值而言,它永远是大于等于0的,这就意味着这是一个死循环,而这也就是这两行代码存在的问题了。

  • 解决
    由于存在的问题很明显,本质上是进入循环的条件永远为真,所以为了解决这个问题,需要修改i的类型或进入的条件。

2.使用列表时对列表进行修改

有如下一段代码,运行后会发生什么:
  for(int i=0;i<actor.length;i++) 
      if(actor[i].blood==0)
          actor.Remove(i);
  • 分析
    这个代码的功能是在满足actor[i].blood==0时,会将对应的actor从列表中移除,但是仔细思考后会发现一个问题,移除之后,列表的长度发生了变化,每次移除,对应的actor的下一个都无法被遍历到,最后会导致列表无法被完整遍历。
  • 解决
    一般情况下我们都是需要对列表中所有的值进行遍历的,如果在遍历的同时还需要对列表进行修改,那么在发生修改时,必须对下标进行修正,修改代码如下:
  for(int i=0;i<actor.length;i++) 
      if(actor[i].blood==0)
        {
              actor.Remove(i);
              i--;//对下标进行修正
         }


3.float值使用==符号

有如下一段代码,它存在什么问题:
  float time=0.0f;
  void PrintTime(float dr)
  {
    if((time-dr)==0.0f)
        Console.Log(time.ToString());
  }
  • 分析
    这几行代码中有一个float型变量 time,和一个满足(time-dr)==0.0f条件后就会输出当前时间的方法。
    要找到问题的所在,首先我们要知道float值有什么特点。

浮点数是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到
——百度百科

所谓浮点数就是小数点在逻辑上是不固定的,而定点数只能表示小数点固定的数值,具用浮点数或定点数表示某哪一种数要看用户赋予了这个数的意义是什么。
——百度百科

一个浮点数a由两个数m和e来表示:a = m × b^e。在任意一个这样的系统中,我们选择一个基数b(记数系统的基)和精度p(即使用多少位来存储)。m(即尾数)是形如±d.ddd...ddd的p位数(每一位是一个介于0到b-1之间的整数,包括0和b-1)。如果m的第一位是非0整数,m称作规格化的。有一些描述使用一个单独的符号位(s 代表+或者-)来表示正负,这样m必须是正的。e是指数。

总之,float型的数值并不是一个准确的值,它的值是根据使用a = m × b^e的格式来表示的,根据精度不同,表示的值的精确度也不同,如果使用==符号,根据drtime当前的值,必然导致它们的差很可能不等于0.0f

  • 解决
    由于浮点数的特点,决定了我们不可能使用==来进行比较,那么要怎么样才能解决这个问题呢?
    我们知道,浮点数是一个近似数,对具体使用而言,只要它在我们指定的精度上满足我们相等的要求就可以了,所以我们可以指定一个精度,只要两个值满足这个精度即可。
    解决代码如下
        float time = 0.0f;
        void PrintTime(float dr)
        {
            if (IsEqual(time, dr))//使用定义的规则进行判断
                Console.Log(time.ToString());
        }

        const float precision = 0.0001f;//定义所需精度
        bool IsEqual(float a, float b)//定义判断方法
        {
            return a > b ? a - b < precision : b - a < precision;
        }

4.类型大小问题

Q:在32位系统中,sizeof(int)和sizeof(int*)的值分别是多少?

  • 分析
    sizeof方法是对一个变量或类型求大小的方法,它会返回这个类型或变量的大小,以byte为单位。
    虽然我们都知道1byte=8bit,但是这里如果对sizeof的单位不了解,可能会写成32。
    通常情况下,int类型的大小由32位表示,即32bit,所以sizeof(int)的值为32/8=4;
    int*是一个指针,指针即寻址空间的地址,它的大小与系统相关,32位系统的指针大小为32bit,所以sizeof(int*)的值也是4。

以上四个是就在这段时间面试里遇到的几个小坑,在这之前从未踩过,暂做一下记录。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值