说在前面
今天鄙人再次学习c++。发现了一些较为坑爹的东西,同时口胡一下define的用法,大神请无视。
区别
看看这个代码:
begin
writeln(58+8>>2);
end.
你们说这个代码的结果是多少?跑一下,结果60,这说明在pascal中 >> 的优先级是高于+的。接着我们继续试验。
#include<cstdio>
int main()
{
printf("%d",58+8>>2);
}
你们说这个代码的运行结果是多少?跑一下,结果居然是16,这说明在c++中+的运算优先级是要高于 >> 的。
没有负数
下午我把pascal乱搞一波,发现c++的数组下标是没有负数的,它的下标是从0开始,而且你若定义数组a[1000],那么数组a最大的下标也只999。
循环
看看这个代码:
for(int i=first[u];i;i=next[i])
{
int v=es[i].to;
if(v==fa)
{
continue;
}
dis[v]=es[i].cost+dfs(v,u);
d+=(dis[v]-ave)*(dis[v]-ave);
son+=dis[v];
}
请pascal选手仔细思考一下为什么在这段代码中continue之后会不会死循环,肯定的是不会。因为在这里这个while循环是用for来定义的,不管是否continuei的值在每一次循环之后都会变成
nexti
,当然就不会死循环。
为了使大家印象更加深刻,我把上面的代码改成pascal版的,
错误代码!
while i<>0 do
begin
v:=edge[i].t;
if v=fa then
begin
continue;
end;
map[v]:=edge[i].w+dfs(v,u);
d:=d+sqr(map[v]-ave);
sonsum:=sonsum+map[v];
i:=edge[i].next;
end;
正确代码
while i<>0 do
begin
v:=edge[i].t;
if v=fa then
begin
i:=edge[i].next;//注意这条语句
continue;
end;
map[v]:=edge[i].w+dfs(v,u);
d:=d+sqr(map[v]-ave);
sonsum:=sonsum+map[v];
i:=edge[i].next;
end;
以上就是今天我发现的pascal与c++的不同之处。接下来随便口胡一下define的用法。define的用法其实只是将它进行简单的替换。
顺便来个例子
#include<cstdio>
#define N 2+5
int main()
{
printf("%d",N*N);
}
你们猜这个代码的运行结果是多少?什么?49。我只能给你一个WA,前面说了宏定义只是简单的替换,那么我们将原式拆开,变成这样:2+5*2+5,所以正确的答案是17。
解决办法
将上面的代码改成这样就可以了。
#include<cstdio>
#define N (2+5)
int main()
{
printf("%d",N*N);
}
再来一个一模一样的例子
#include<cstdio>
#define N(a,b) a*b
int main()
{
printf("%d",N(3+7,7+5));
}
将原式展开,变成3+7*7+5=57,可别又算成120。
解决方法
仿照刚才的做法
#include<cstdio>
#define N(a,b) (a)*(b)
int main()
{
printf("%d",N(3+7,7+5));
}
但是我们到这里就结束了吗?当然没有,假如我们要计算
(3+7)*(5+7)/(4*5)的值,我们直接调用N(3+7,5+7)/N(4,5),然而这是正确的吗?按照上面的我们进行直接替换,变成了什么?
(3+7)*(5+7)/4*5=150,不是我们预期的6,怎么办,再加一个括号。
解决办法
#include<cstdio>
#define N(a,b) ((a)*(b))
int main()
{
printf("%d",N(3+7,7+5)/N(4,5));
}
the end
由于我还是c++的新手,在很大程度上会写错,希望大家批评指正,thank you for your patience.。