想起来前段时间某同学给我做的一道题目,很BT-_-

求(1 – 1/2 + 1/3 – 1/4 + … – 1/48 + 1/49 – 1/50)/ (1/26 + 1/27 + 1/28 + … + 1/49 + 1/50)的值。

用中文表述就是 1到50中所有的奇数的倒数和与所有的偶数的倒数和之差除以26到50的倒数和 -_-

Continue reading »

182009
 

运算符重载一直是一个很诡异事情,因为在写代码的时候,不知道某个运算符有没有被重载过。在C++里面,运算符重载可以写在类的外面,当intellisense不工作的时候,找到一个运算符的重载函数是一件相当头疼的事情。这个问题在C#中改善了不少,因为运算符重载一定要写在类内,而且intellisense很强大。不过另一个问题又产生了……

先来看C++中的“==”重载:

1
2
3
4
5
6
7
8
9
struct A{
    int x;
    int y;
};

inline
bool operator == (const A& a, const A& b){
    return a.x == b.x && a.y == b.y;
}

上面这段代码中,由于声明的关系,a和b永远不可能为NULL,所以直接调用a.x和b.x是没有问题的。

而在C#中:

1
2
3
4
5
6
7
8
9
10
11
12
struct A
{
    public int x, y;
    public static bool operator ==(A a, A b)
    {
        return a.x == b.x && a.y == b.y;
    }
    public static bool operator !=(A a, A b)
    {
        return !(a == b);
    }
}

这段代码是没问题的,因为A是struct,而struct不可能为null。但换成class就有问题了,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    class A
    {
        public int x, y;
        public static bool operator ==(A a, A b)
        {
            if (a == null && b == null)
            {
                return true;
            }
            if (a == null || b == null)
            {
                return false;
            }
            return a.x == b.x && a.y == b.y;
        }
        public static bool operator !=(A a, A b)
        {
            return !(a == b);
        }
    }

由于reference type可以为null,所以要先检查a和b是不是null,但是“a == null”这一句又会去调用“operator ==”,于是就无限递归下去了……想了很久都没想出来变通的方法,而且System.String的实现也很诡异:

1
2
3
4
5
6
7
8
public static bool operator ==(string a, string b)
{
    return Equals(a, b);
}
public static bool Equals(string a, string b)
{
    return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b)));
}

看上去也会无限递归的(Reflector出来的,不一定准),很神奇……

虽然对于Referece type不建议重载==,但是不建议并不代表不能用吧,这个设计太挫了……

 

XmlHttpRequest里面常用的函数和属性无非就这几个:

open(method, url, async, user, password)

其中method的值多数为Get或者Post(不区分大小写)用于从服务器获取数据和向服务器发送数据,还有Head, Put, Delete之类的,基本不会用到;url是实际要访问的url地址,比如http://leonax.net;async的值为true或者false,表示是否要以异步模式(即非阻塞模式)进行通信;user和password为访问url所需的用户名和密码,一般都是省略掉的。

open函数只是初始化一下Xmlhttp对象,它并不会向url所对应的服务器发送数据。比较奇怪的是,W3C的规范中async的缺省值为true,也就是说,以下代码会以异步模式运行:

1
2
3
var xmlhttp = NewXmlHttpRequest();
xmlhttp.open("Get", "http://leonax.net");
xmlhttp.send();

Msxml3和IE的XmlHttpRequest遵循了这一规范,而Msxml6中的缺省值为false。既然缺省值都为true,为什么不把参数名改成sync呢?在Javascript(以及各种脚本语言)中,缺省参数一般为null,而null和false等价,所以把缺省值定为true实在是太令人费解了。

send(text)

真正把数据发出去的是这个函数。text可以是任何值,它会被当作数据包的正文发给服务器。

在open之前调用send会报错。

以异步模式open之后,send函数会立刻返回;相反,在同步模式的时候,它会等到接收完服务器所有的回应才返回。

responseText

这是一个属性,在收到服务器的回复之后,可以通过它来查看回复的正文部分。如:

1
2
3
4
var xmlhttp = NewXmlHttpRequest();
xmlhttp.open("Get", "http://leonax.net", false);
xmlhttp.send();
alert(xmlhttp.responseText);

将显示出一个很简易的Html :P。在未完全收到回复之前,responseText返回一个空字符串。

© 2004 - 2011 Leona+Suffusion theme by Sayontan Sinha