说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

一个c#程序员的感慨:即使简单,仍然出错

编辑:说三道四文库 发布时间:2018-07-23 04:06
HTML文档下载 WORD文档下载 PDF文档下载
using System;
namespace Param
{
class Class1
{
static int i = getNum();
int j = getNum();
static int num = 1;
static int getNum()
{
return num;
}
[STAThread]
static void Main(string[] args)
{
Console.WriteLine(string.Format("i={0}",i));
Console.WriteLine(string.Format("j={0}",new Class1().j));
}
}
}
上面的代码是一个网友告诉我的,让我看看结果,我看了一眼马上说结果是
i=1
j=1
网友运行后说结果是
i=0
j=1
我吓了一跳,认真看了代码,原来自己真的错了。
下面我解释一下为什么是后一种结果
对一个类来说,static变量是与对象无关的,那么它们什么时候被初始化呢?就是在第一次引用的时候。当类生成对象的时候,可以简单分成3步
1,为所有static变量分配内存,这个时候内存里面的值是该变量类型的缺省值。关于不同值类型的缺省值大家可以去查相关资料,注意值类型和引用类型是不同的。
2,为static变量赋值,同样要注意值类型和引用类型是不同的。
3,生成对象,调用构造函数,先调用这个类的父类的构造函数,然后调用类本身的构造函数,生成对象。
现在分析上面的代码:
Console.WriteLine(string.Format("i={0}",i));这里i是static变量,而且类class1是第一次被引用,按照上面说的三步,要先为class1里面所有的static变量分配内存。尽管现在有超线程技术,但是指令在逻辑还是一条一条的按顺序执行的,所以先为static int i分配内存,并且在该内存中保持int的缺省值0,接着再为static int num 变量分配内存,值当然也为0。
然后执行第二步,为变量赋值:先为static int i变量赋值,i=getNum(),看getNum里面的代码,就是return num,这个时候num的值是0,于是i就为0了。然后对变量num赋值,num=1;这行代码执行后,num就为1了。分析到这里我就不继续分析了,大家很容易看出结果是什么。

稍微熟悉c#的人,只要认真看代码,肯定不会出错,但是如果拿来考人,相信很多人会做错。我认为这个问题简单得算不上一个技术问题,所以放在非技术区。之所以在上面说那么多废话来分析,是想说明在编程的时候,即使非常熟悉、非常基本的东西,也要认真。当然如果我手下的人写出这样的代码,肯定在代码检视的时候被我痛批。事实上对static 值类型变量不直接赋值,而通过方法来赋值,是不常用或者是有点bt的做法,但是我仍然很佩服出题的人。
诚如楼主所言,“对static 值类型变量不直接赋值,而通过方法来赋值,是不常用或者是有点bt的做法”,这样的题可以拿来做考试题,帮助辩明概念,实用价值不高,^_^
题目是我出的,
最近我在自己的blog里面写了一系列关于C#的基础知识的笔试题,
网址http://www.cnblogs.com/jjstar/
希望所有人都来检查一下自己的基础是否夯实,
有句话说的好:勿在浮沙建高塔
... ...
up
看样子我得更努力了
只有中国人才会出这样题。舍大求小
有什么值得佩服的,简直BT!
老实说,在干活时遇到这样的问题,有点基础的程序员都会主动去检查并能找出原因的。楼主应该把它做为经验向你的同事推广以避免走弯路或知道问题要害而不是去痛批。

何况,写代码写多了,再浮燥的代码员都会变得越来越谨慎的。

如果Richard Stallman在你“手下”不小心地把"=="写成"=",你是不是就会去“痛批”他呢?

你的"只要认真看代码,肯定不会出错", 你敢肯定?否则要调试器干嘛呀?




弓虽!,果然BT。
死扣墙脚
to chixiao(鸱鸮):
呵呵,我说“痛批”可能有点夸张了。

如果Richard Stallman在我“手下”不小心地把"=="写成"=",我也同样“痛批”,应该针对事情,而不要针对人,不管他是新手还是名人。 我进入it行业不久,真的不知道Richard Stallman是谁。呵呵。

“你的"只要认真看代码,肯定不会出错", 你敢肯定?否则要调试器干嘛呀?”----我说的是对上面那段代码啊,我敢肯定上面那段代码如果我认真看,不会出错。我没有说所有的代码都不需要调试器啊。看来你看我的话没有认真啦。

我认为自己对c#语法还比较熟悉,觉得上面的代码也很简单,没有想到会做错。我写出来是希望能引起大家重视,在对待简单问题的时候也要认真,不是为了批评出题的人;相反,我很佩服出题的人。可能是我的表达能力太差,没有说明白。郁闷中。

我认为static破坏了面向对象的设计思想,但是它的确非常有用。我对oo理论学的不多,但是记得有两条:1,对象独立存在;2,一个对象无法改变另外一个对象的状态。static有全局变量的作用,很显然,使用static破坏了这两条,容易引起潜在的危险。大多数公司的编码规范中,应该有对static使用条件限制做详细规定。

在实际开发中,上面的写法肯定是不对的。我相信作为出题人的jjstar(陈叙远)先生,目的也不是教大家在实际工作的时候这样写代码,而是让大家注意基础。不知道我说的对不对,请jjstar(陈叙远)先生指正。谢谢。
我在想,楼主适合去咱们国家的计算机等级考试院工作。编程不是这么学D。
要当程序员,还是要用最先进的编程工具来实现用户需要。没有必要再怀念汇编这样底层的东西。
如果你非要追求底层的东西,那就还是去读博读后搞研究比较合适。
又看到楼主的文章了,写得不错。以前看楼主的那篇“我的程序员之路”非常感动啊!
http://community.csdn.net/Expert/topic/3341/3341074.xml?temp=.8406946
不要把自己限制死了,寸有所长,尺有所短,扬长避短,只要在乎用最好的方式达到目的就可以了。
惭愧,我在工作中就是尽快完成工作,老板一般一逼得紧,根本没时间去考虑很多基本的问题。
还是多抽时间学习了。
中国人的软件水平(包括整个教育和科研水平上不去)真是因为这样的 BT 东西太多了。
中国人最喜欢钻牛角尖,这是一个典型。

说得好听一点,这些 BT 的东西属于“学院风格”。
在工程实践中,工程师不能像研究员那样没有时间和成本压力的去思考或实践。
更改为:
using System;
namespace Param
{
class Class1
{
                  static int num = 1;
static int i = getNum();
int j = getNum();
static int getNum()
{
return num;
}
[STAThread]
static void Main(string[] args)
{
Console.WriteLine(string.Format("i={0}",i));
Console.WriteLine(string.Format("j={0}",new Class1().j));
}
}
}
输出就是:
i=1
j=1
刚才试验了一下
在C++中:
i=1
j=1
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘