写了个api,被人调用,coresearch_get_del2.php?type=deluser&uid=1456736567 发现有人用如下方式调用:
coresearch_get_del2.php?type=deluser&uid=
为空,于是本人用isset来判断失败了,最后修改为:
if(!strlen(trim($uid)))
{
echo "trim space has no number";
exit(0);
}
最好修改为:
if(empty($uid))
{
echo "trim space find has no number,is empty?";
exit(0);
}
看看区别url:
http://www.g168.net/html/PHP_006/2007/1216/20076531760459.html
Empty函数:
一)无论是Null还是真的是空:'' 用empty都能正确判断返回1值:
---------- 调试PHP ----------
11
输出完成 (耗时 0 秒) - 正常终止
二)对连接Memcache里没有值的情况其返回为false值,用empty也能判断:
---------- 调试PHP ----------
Get key1 value: This is first value
bool(false)
bool(true)
输出完成 (耗时 0 秒) - 正常终止
总之,empty函数对真的空,Null,及bool的false都能判断正确。
网上:empty:
如果 变量 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var、未定义; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。
来自:http://www.cnblogs.com/chengmo/archive/2010/10/18/1854258.html
coresearch_get_del2.php?type=deluser&uid=
为空,于是本人用isset来判断失败了,最后修改为:
if(!strlen(trim($uid)))
{
echo "trim space has no number";
exit(0);
}
最好修改为:
if(empty($uid))
{
echo "trim space find has no number,is empty?";
exit(0);
}
看看区别url:
http://www.g168.net/html/PHP_006/2007/1216/20076531760459.html
Empty函数:
一)无论是Null还是真的是空:'' 用empty都能正确判断返回1值:
---------- 调试PHP ----------
11
输出完成 (耗时 0 秒) - 正常终止
二)对连接Memcache里没有值的情况其返回为false值,用empty也能判断:
---------- 调试PHP ----------
Get key1 value: This is first value
bool(false)
bool(true)
输出完成 (耗时 0 秒) - 正常终止
总之,empty函数对真的空,Null,及bool的false都能判断正确。
网上:empty:
如果 变量 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var、未定义; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。
来自:http://www.cnblogs.com/chengmo/archive/2010/10/18/1854258.html
重启:
重启二:
关机一:
关机二:
[root@localhost ~]# init 0 //关机
[root@localhost ~]# init 1 //切换到单用户模式/救援模式
[root@localhost ~]# init 2 //切换到无网络连接的多用户命令行模式
[root@localhost ~]# init 3 //切换到有网络连接的多用户命令行模式
[root@localhost ~]# init 4 //不可用
[root@localhost ~]# init 5 //切换到带图形界面的多用户模式
[root@localhost ~]# init 6 //重启
本文出自:LinuxAid.com.cn 作者: sword_martin (2002-01-30 21:03:06)
在linux下一些常用的关机/重启命令有shutdown、halt、reboot、及init,它们都
可以达到重启系统的目的,但每个命令的内部工作过程是不同的,通过本文的介绍,希
望你可以更加灵活的运用各种关机命令。
1.shutdown
shutdown命令安全地将系统关机。 有些用户会使用直接断掉电源的方式来关闭linux,
这是十分危险的。因为linux与windows不同,其后台运行着许多进程,所以强制关机可能
会导致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备。
而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭。
并且login指令会被冻结﹐即新的用户不能再登录。直接关机或者延迟一定的时间才关机
都是可能的﹐还可能重启。这是由所有进程〔process〕都会收到系统所送达的信号〔signal〕
决定的。这让像vi之类的程序有时间储存目前正在编辑的文档﹐而像处理邮件〔mail〕和
新闻〔news〕的程序则可以正常地离开等等。
shutdown执行它的工作是送信号〔signal〕给init程序﹐要求它改变runlevel。
Runlevel 0被用来停机〔halt〕﹐runlevel 6是用来重新激活〔reboot〕系统﹐
而runlevel 1则是被用来让系统进入管理工作可以进行的状态﹔这是预设的﹐假定没有-h也
没有-r参数给shutdown。要想了解在停机〔halt〕或者重新开机〔reboot〕过程中做了哪些
动作﹐你可以在这个文件/etc/inittab里看到这些runlevels相关的资料。
shutdown 参数说明:
[-t] 在改变到其它runlevel之前﹐告诉init多久以后关机。
[-r] 重启计算器。
[-k] 并不真正关机﹐只是送警告信号给每位登录者〔login〕。
[-h] 关机后关闭电源〔halt〕。
[-n] 不用init﹐而是自己来关机。不鼓励使用这个选项﹐而且该选项所产生的后果往
往不总是你所预期得到的。
[-c] cancel current process取消目前正在执行的关机程序。所以这个选项当然没有
时间参数﹐但是可以输入一个用来解释的讯息﹐而这信息将会送到每位使用者。
[-f] 在重启计算器〔reboot〕时忽略fsck。
[-F] 在重启计算器〔reboot〕时强迫fsck。
[-time] 设定关机〔shutdown〕前的时间。
2.halt----最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐
文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超
级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
3.reboot
reboot的工作过程差不多跟halt一样﹐不过它是引发主机重启﹐而halt是关机。它
的参数与halt相差不多。
4.init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的
用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),
init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有
telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐
并且得不到使用shutdown时的信息和等待时间。
1关机命令 shutdown
好像ubuntu的终端中默认的是当前用户的命令,只是普通用户,因此在终端器中可以使用sudo -sh 转换到管理员root用户下执行命令。
1)shutdown --help
可以查看shutdown命令如何使用,当然也可以使用man shutdown命令。
2) shutdown -h now 现在立即关机
3)shutdown -r now 现在立即重启 , 或者 init 6 //重启 init 1是单用户级别, Init6才 是重新启动。
4)shutdown -r +3 三分钟后重启
5)shutdown -h +3 "The System will shutdown after 3 minutes" 提示使用者将在三分钟后关机
6)shutdown -r 20:23 在20:23时将重启计算机
7)shutdown -r 20:23 & 可以将在20:23时重启的任务放到后台去,用户可以继续操作终端
2中断命令
1)执行完命令后(若没有转到后台),可以使用CTRL+C来中止命令
2)kill 程序编码
当命令在后台执行时系统会返回一个程序编码,例如:在使用 shutdown -r 20:23 & 系统返回系统编码:4905
我们可以使用kill 4905来中止重启命令
3ps aux | grep 程序编号
我们如果知道程序的编号,我们可以使用ps aux |grep 程序编号来查询该程序编号对应的命令是什么。
例如上面的程序编号为4905 ,我们可以使用ps aux | grep 4905 就可以查到 shutdown -r 20:23 & 的命令
halt—-最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐并且得不到使用shutdown时的信息和等待时间。
注销系统的logout命令
Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:
[root@localhost root]#logout
Red Hat Linuxrelease 9(Shike)
Kernel 2.4.20.8 on an i686
Login: ← 回到登陆的画面
重启二:
关机一:
关机二:
[root@localhost ~]# init 0 //关机
[root@localhost ~]# init 1 //切换到单用户模式/救援模式
[root@localhost ~]# init 2 //切换到无网络连接的多用户命令行模式
[root@localhost ~]# init 3 //切换到有网络连接的多用户命令行模式
[root@localhost ~]# init 4 //不可用
[root@localhost ~]# init 5 //切换到带图形界面的多用户模式
[root@localhost ~]# init 6 //重启
本文出自:LinuxAid.com.cn 作者: sword_martin (2002-01-30 21:03:06)
在linux下一些常用的关机/重启命令有shutdown、halt、reboot、及init,它们都
可以达到重启系统的目的,但每个命令的内部工作过程是不同的,通过本文的介绍,希
望你可以更加灵活的运用各种关机命令。
1.shutdown
shutdown命令安全地将系统关机。 有些用户会使用直接断掉电源的方式来关闭linux,
这是十分危险的。因为linux与windows不同,其后台运行着许多进程,所以强制关机可能
会导致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备。
而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭。
并且login指令会被冻结﹐即新的用户不能再登录。直接关机或者延迟一定的时间才关机
都是可能的﹐还可能重启。这是由所有进程〔process〕都会收到系统所送达的信号〔signal〕
决定的。这让像vi之类的程序有时间储存目前正在编辑的文档﹐而像处理邮件〔mail〕和
新闻〔news〕的程序则可以正常地离开等等。
shutdown执行它的工作是送信号〔signal〕给init程序﹐要求它改变runlevel。
Runlevel 0被用来停机〔halt〕﹐runlevel 6是用来重新激活〔reboot〕系统﹐
而runlevel 1则是被用来让系统进入管理工作可以进行的状态﹔这是预设的﹐假定没有-h也
没有-r参数给shutdown。要想了解在停机〔halt〕或者重新开机〔reboot〕过程中做了哪些
动作﹐你可以在这个文件/etc/inittab里看到这些runlevels相关的资料。
shutdown 参数说明:
[-t] 在改变到其它runlevel之前﹐告诉init多久以后关机。
[-r] 重启计算器。
[-k] 并不真正关机﹐只是送警告信号给每位登录者〔login〕。
[-h] 关机后关闭电源〔halt〕。
[-n] 不用init﹐而是自己来关机。不鼓励使用这个选项﹐而且该选项所产生的后果往
往不总是你所预期得到的。
[-c] cancel current process取消目前正在执行的关机程序。所以这个选项当然没有
时间参数﹐但是可以输入一个用来解释的讯息﹐而这信息将会送到每位使用者。
[-f] 在重启计算器〔reboot〕时忽略fsck。
[-F] 在重启计算器〔reboot〕时强迫fsck。
[-time] 设定关机〔shutdown〕前的时间。
2.halt----最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐
文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超
级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
3.reboot
reboot的工作过程差不多跟halt一样﹐不过它是引发主机重启﹐而halt是关机。它
的参数与halt相差不多。
4.init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的
用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),
init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有
telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐
并且得不到使用shutdown时的信息和等待时间。
1关机命令 shutdown
好像ubuntu的终端中默认的是当前用户的命令,只是普通用户,因此在终端器中可以使用sudo -sh 转换到管理员root用户下执行命令。
1)shutdown --help
可以查看shutdown命令如何使用,当然也可以使用man shutdown命令。
2) shutdown -h now 现在立即关机
3)shutdown -r now 现在立即重启 , 或者 init 6 //重启 init 1是单用户级别, Init6才 是重新启动。
4)shutdown -r +3 三分钟后重启
5)shutdown -h +3 "The System will shutdown after 3 minutes" 提示使用者将在三分钟后关机
6)shutdown -r 20:23 在20:23时将重启计算机
7)shutdown -r 20:23 & 可以将在20:23时重启的任务放到后台去,用户可以继续操作终端
2中断命令
1)执行完命令后(若没有转到后台),可以使用CTRL+C来中止命令
2)kill 程序编码
当命令在后台执行时系统会返回一个程序编码,例如:在使用 shutdown -r 20:23 & 系统返回系统编码:4905
我们可以使用kill 4905来中止重启命令
3ps aux | grep 程序编号
我们如果知道程序的编号,我们可以使用ps aux |grep 程序编号来查询该程序编号对应的命令是什么。
例如上面的程序编号为4905 ,我们可以使用ps aux | grep 4905 就可以查到 shutdown -r 20:23 & 的命令
halt—-最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐并且得不到使用shutdown时的信息和等待时间。
注销系统的logout命令
Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:
[root@localhost root]#logout
Red Hat Linuxrelease 9(Shike)
Kernel 2.4.20.8 on an i686
Login: ← 回到登陆的画面
由于要作项目开发,考虑到就几个人同时开发,于是想用下CVS
CVS ---Concurrent Versions system(并发版本管理系统)是一个版本控制管理系统,他是目前最为广泛使用的一个系统.大家只要曾经下载过linux的软件源代码(比如tar.gz的文件)你可以在没一个目录下看到CVS目录,那就说明他的软件是CVS进行控制的.
目前基本上流行的Linux发布版本都自带有cvs.
CVS初始化
---------------------------------
----------------------------------
环境设置:指定CVS库的路径CVSROOT
tcsh中设置
setenv CVSROOT /yourpath
bash中设置
export CVSROOT=/yourpath
初始化:
%cvs init
这时会在你的$CVSROOT目录下产生CVSROOT目录,下面是他生成的一些文件.
尽量不要去改变他.
一个项目的导入:
现在把我们的项目导入到CVS中去
%cvs import -m "your comment message" yourprojectname vendor_tag release_tag
执行后,会把当前目录下的所有文件(包括子目录)导入到/yourpath/yourprojectname目录中去
vender_tag:开发伤标记
release_tag:版本发布标记
现在你可以删去原来的源代码了.
ok,现在可以使用CVS了,找到一个合适的目录执行
%cvs checkout project_name
cvs将创建project_name目录,并将最新版本的源代码导出到相应的目录中.
CVS的基本使用
----------------------------------
----------------------------------
当你执行过cvs checkout,就不要来再次导出了,以后只要使用
%cvs update
来同步文件,如果连带子目录也要同步,就必需使用
%cvs update -d 了.
添加文件:
当你新写了一个文件后,可以使用
%cvs add filename来提交
这时其实文件并没有真正的提交,\如果要确定提交,使用下面的命令
%cvs commit -m "your comment"
删除文件:
%cvs rm filename
%cvs commit -m "why delete this file(s)"
导出发布不代CVS目录的源代码
如果系统完成了,需要发布,使用cvs export命令,不过export只是针对一个TAG或者日期导出,可以是这些命令方式:
%cvs export -r release1 project_name
%cvs export -D 20040303 project_name
%cvs export -D now project_name
对于cvs client端,如果使用linux,则已经有了,如果是windows,就使用wincvs吧.
这里要考虑到cvs的远程认证,我们使用cvs本身的pserver的认证方式
首先在服务器端建立启动文件
#cd /etc/xinted.d/
#cat cvsperver
# default: off
service cvspserver
{
disable = no
port = 2401
socket_type = stream
wait = no
#only_from = 127.0.0.1
user = apache
server = /usr/bin/cvs
passenv =/wpm-source/CVSROOT/passwd
server_args =-f --allow-root=/wpm-source pserver
log_on_failure += USERID
}
重新启动xinted
#kill -HUP xinted
然后进入你的$CVSROOT/CVSROOT目录,要建立passwd文件
这个文件的格式是
username:password:map_system_user
其中密码加密方式和apache中的加密方式一样,于是我们可以这样作:
#htpasswd -c passwd yourname
#cat passwd
yourname:sEylx9?G:apache
注意passwd文件后面的passwd是后来手工加入的.
如果你觉得这样麻烦,你可以使用cvstrac来管理.
cvstrac可以在
http://www.cvstrac.org
下载,我使用了,暂时还没有发现他的好处.
在客户端使用下面的命令来将项目导出
%cvs -d :pserver:yourname@yourip(or hostanme)#port/yourcvsroot checkout yourprojectname
这样就会在当前目录下建立yourprojectname的目录了.
现在你就可以在这个目录下做你的工作了.做完后,使用cvs基本使用中提到的命令来修改,更新和添加文件,就象在本地使用一样.
你最好设立这样的环境变量,这样下次开机就不要输入重复的命令
在/etc/profile文件中加入这样两行
CVSROOT=:pserver:yourname@cvsrootipaddress#port/cvsroot
export CVSROOT
就可以了.
使用感想: 阅读全文
CVS ---Concurrent Versions system(并发版本管理系统)是一个版本控制管理系统,他是目前最为广泛使用的一个系统.大家只要曾经下载过linux的软件源代码(比如tar.gz的文件)你可以在没一个目录下看到CVS目录,那就说明他的软件是CVS进行控制的.
目前基本上流行的Linux发布版本都自带有cvs.
CVS初始化
---------------------------------
----------------------------------
环境设置:指定CVS库的路径CVSROOT
tcsh中设置
setenv CVSROOT /yourpath
bash中设置
export CVSROOT=/yourpath
初始化:
%cvs init
这时会在你的$CVSROOT目录下产生CVSROOT目录,下面是他生成的一些文件.
尽量不要去改变他.
一个项目的导入:
现在把我们的项目导入到CVS中去
%cvs import -m "your comment message" yourprojectname vendor_tag release_tag
执行后,会把当前目录下的所有文件(包括子目录)导入到/yourpath/yourprojectname目录中去
vender_tag:开发伤标记
release_tag:版本发布标记
现在你可以删去原来的源代码了.
ok,现在可以使用CVS了,找到一个合适的目录执行
%cvs checkout project_name
cvs将创建project_name目录,并将最新版本的源代码导出到相应的目录中.
CVS的基本使用
----------------------------------
----------------------------------
当你执行过cvs checkout,就不要来再次导出了,以后只要使用
%cvs update
来同步文件,如果连带子目录也要同步,就必需使用
%cvs update -d 了.
添加文件:
当你新写了一个文件后,可以使用
%cvs add filename来提交
这时其实文件并没有真正的提交,\如果要确定提交,使用下面的命令
%cvs commit -m "your comment"
删除文件:
%cvs rm filename
%cvs commit -m "why delete this file(s)"
导出发布不代CVS目录的源代码
如果系统完成了,需要发布,使用cvs export命令,不过export只是针对一个TAG或者日期导出,可以是这些命令方式:
%cvs export -r release1 project_name
%cvs export -D 20040303 project_name
%cvs export -D now project_name
对于cvs client端,如果使用linux,则已经有了,如果是windows,就使用wincvs吧.
这里要考虑到cvs的远程认证,我们使用cvs本身的pserver的认证方式
首先在服务器端建立启动文件
#cd /etc/xinted.d/
#cat cvsperver
# default: off
service cvspserver
{
disable = no
port = 2401
socket_type = stream
wait = no
#only_from = 127.0.0.1
user = apache
server = /usr/bin/cvs
passenv =/wpm-source/CVSROOT/passwd
server_args =-f --allow-root=/wpm-source pserver
log_on_failure += USERID
}
重新启动xinted
#kill -HUP xinted
然后进入你的$CVSROOT/CVSROOT目录,要建立passwd文件
这个文件的格式是
username:password:map_system_user
其中密码加密方式和apache中的加密方式一样,于是我们可以这样作:
#htpasswd -c passwd yourname
#cat passwd
yourname:sEylx9?G:apache
注意passwd文件后面的passwd是后来手工加入的.
如果你觉得这样麻烦,你可以使用cvstrac来管理.
cvstrac可以在
http://www.cvstrac.org
下载,我使用了,暂时还没有发现他的好处.
在客户端使用下面的命令来将项目导出
%cvs -d :pserver:yourname@yourip(or hostanme)#port/yourcvsroot checkout yourprojectname
这样就会在当前目录下建立yourprojectname的目录了.
现在你就可以在这个目录下做你的工作了.做完后,使用cvs基本使用中提到的命令来修改,更新和添加文件,就象在本地使用一样.
你最好设立这样的环境变量,这样下次开机就不要输入重复的命令
在/etc/profile文件中加入这样两行
CVSROOT=:pserver:yourname@cvsrootipaddress#port/cvsroot
export CVSROOT
就可以了.
使用感想: 阅读全文
在许多Web编程里,字符串总是会被大量地生成和处理的。正确地使用和处理字符串,对于PHP程
序员来说也同样越来越重要了。本文从最简单的字符串定义一直引导你到高层字符串处理技巧,希望
对大家有所帮助。
一、引号定义字符串
在PHP中,通常一个字符串被定义在一对引号中,如:
'I am a string in single quotes'
"I am a string in double quotes"
PHP语法分析器是用成对的引号来判断一个字符串的。因此,所有字符串必须使用同一种单或者双
引号来定义开始和结束。例如,下面的字串定义是不合法的:
"I am not a valid string since I have unmatching quote marks'
'Me neither!"
定义字符串时,只有一种引号被视为定义符,即单引号或双引号。于是,如果一个字符串由双引
号开始,那么只有双引号被分析器解析。这样,你就可以在双引号串中包含任何其他字符,甚至单引
号。下面的引号串都是合法的:
$s = "I am a 'single quote string' inside a double quote string";
$s = 'I am a "double quote string" inside a single quote string';
当PHP遇到与串的开头相对应的引号时,便认为已经到了字符串尾部,于是:
"Why doesn't "this" work?" 阅读全文
序员来说也同样越来越重要了。本文从最简单的字符串定义一直引导你到高层字符串处理技巧,希望
对大家有所帮助。
一、引号定义字符串
在PHP中,通常一个字符串被定义在一对引号中,如:
'I am a string in single quotes'
"I am a string in double quotes"
PHP语法分析器是用成对的引号来判断一个字符串的。因此,所有字符串必须使用同一种单或者双
引号来定义开始和结束。例如,下面的字串定义是不合法的:
"I am not a valid string since I have unmatching quote marks'
'Me neither!"
定义字符串时,只有一种引号被视为定义符,即单引号或双引号。于是,如果一个字符串由双引
号开始,那么只有双引号被分析器解析。这样,你就可以在双引号串中包含任何其他字符,甚至单引
号。下面的引号串都是合法的:
$s = "I am a 'single quote string' inside a double quote string";
$s = 'I am a "double quote string" inside a single quote string';
当PHP遇到与串的开头相对应的引号时,便认为已经到了字符串尾部,于是:
"Why doesn't "this" work?" 阅读全文
前段时间有人问关于C++的继承与多态的问题,当时一边调试一边讲解也算是解释通了,但后来又有朋友问起此问题,便想写点这方面的东西,问题是这样的:
#include<iostream.h>
class base
{
public:
func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
就是这样一个程序,得到的结果是什么呢?答案是:”this is base class”,而问题就在于这一句话:base* p=new x,程序的本意可能是要创建一个x 的对象,但为什么执行的是base的func呢?我们先来看一下new用法,new的作用在堆里为象分配内存并为这块内存调用构造函数,并且内置了长度计算,类型转换和安全检查,通用的格式是Type *p=new Type,而在程序中使用的是base* p=new x,这样就产生了第一个问题,p到底是指向base还是指向x,按照通用的格式应该指向Type,但到底是前面的Type还是后面的Type呢?于是我便把base* p=new x 改成了x* p=new base结果出错,编译器提示不能把类型base转变成x,看来当前一个Type和后一个Type的型类不一致是会发生类型转换,正好new的内置功能里带用类型转换,不难看出这里是把第二个Type转换成第一个Type,但为什么当把base转换成x时会出误错呢?这里就引出了个上向类型转换的概念,所谓上向类型转换就是取一个对象的地址,并将其作为基类的地址一处理,也就是说只能由子类向父类转换.综合上面的解释,程序中实际上是创建了一个base类型的对象,为了证明的我结论是正确的,我又作了以下调式,在base类中添加一个函数a,在x中添加了一函数b,因为x是继承base.所以如果p是x的话那么它可以调用父类的函数a,也可以调用x类的函数b,反之则只能调到base类的函数a,而不能调用x的函数b,调式发现,结果和我想像的是相符合的,也证明了以上的结论.
其实到这里只是完成了整个问题的第一步,于是继续修改程序:
我把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
这种里的修改是把func改成了虚函数,再执行,结果是:”this is x class”,这个结果似乎有点出乎意料,似乎和我第一步的结论相反,但第一步是论证是比较严谨的,于是我把注意力集中到了虚函数上.要找到本质原因,还得从虚函数的现实讲起,我们来看一下虚函数是怎样实现的,
把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
x* p=new x;
p->func();
}
注意,这里主要改的是x* p=new x,建一个x对象,则由于func函数是一个虚函数,所在这里应该调用的是x的func而当func不是虚函数时,则调用base的func函数,虚函数和普通函数到底有什么区别?编译器又是怎么处理的?我们来作一个测式,写如下程序:
#include <iostream.h>
class X{
int i;
public:
a()
{
}
};
class Y{
int i;
public:
virtual a()
{
}
};
class Z{
int i;
public:
virtual a()
{
}
virtual b()
{
}
};
void main()
{
cout<<sizeof(X)<<endl;
cout<<sizeof(Y)<<endl;
cout<<sizeof(Z)<<endl;
}
这样我们可以得到三个类的大小,分别是:4,8,8类X与类Y的构构基本相同但Y的大小是X的两倍,而X与Y的不同点就是Y的a是一个虚函数,而Y与Z的大小是相同的,但Z有两个虚函数,而Y只是一个虚函数,得出这样的结果的原因是因为不带虚函数的对象的长度是单个int的长度,而带有单个虚函数的对象长度是不带虚函数的长度再加上一个指针的长度,实际是编译器在Y中插入了一个指针(VPTR),所以带一个虚函数和带两个虚函数没有区别,都只插入了一个指针,而这个指针指向一个存放函数地址的表(虚函数据表),这个表存放着具体函数。我们用函数图来画出函数的结构:
难点就在于虚函数表的内容是依据类中的虚函数声明次序,一一填入函数指针,子类会继承父类的虚函数表,当我们在改写子类时,虚函数表就受了影响:表中元素指的函数地址不再是父类的函数地址,而是子类的函数地址。所以当我们创建一个X对像的时候,编译器能知道执行的是X的func
我们再来看:base* p=new X
前面我们讲了这里是按照向上类型转换的原则把X转换成了base,而此时baser的VPTR指针会指向X的虚函数表,所以,p->func()会执行X的func函数.
#include<iostream.h>
class base
{
public:
func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
就是这样一个程序,得到的结果是什么呢?答案是:”this is base class”,而问题就在于这一句话:base* p=new x,程序的本意可能是要创建一个x 的对象,但为什么执行的是base的func呢?我们先来看一下new用法,new的作用在堆里为象分配内存并为这块内存调用构造函数,并且内置了长度计算,类型转换和安全检查,通用的格式是Type *p=new Type,而在程序中使用的是base* p=new x,这样就产生了第一个问题,p到底是指向base还是指向x,按照通用的格式应该指向Type,但到底是前面的Type还是后面的Type呢?于是我便把base* p=new x 改成了x* p=new base结果出错,编译器提示不能把类型base转变成x,看来当前一个Type和后一个Type的型类不一致是会发生类型转换,正好new的内置功能里带用类型转换,不难看出这里是把第二个Type转换成第一个Type,但为什么当把base转换成x时会出误错呢?这里就引出了个上向类型转换的概念,所谓上向类型转换就是取一个对象的地址,并将其作为基类的地址一处理,也就是说只能由子类向父类转换.综合上面的解释,程序中实际上是创建了一个base类型的对象,为了证明的我结论是正确的,我又作了以下调式,在base类中添加一个函数a,在x中添加了一函数b,因为x是继承base.所以如果p是x的话那么它可以调用父类的函数a,也可以调用x类的函数b,反之则只能调到base类的函数a,而不能调用x的函数b,调式发现,结果和我想像的是相符合的,也证明了以上的结论.
其实到这里只是完成了整个问题的第一步,于是继续修改程序:
我把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
这种里的修改是把func改成了虚函数,再执行,结果是:”this is x class”,这个结果似乎有点出乎意料,似乎和我第一步的结论相反,但第一步是论证是比较严谨的,于是我把注意力集中到了虚函数上.要找到本质原因,还得从虚函数的现实讲起,我们来看一下虚函数是怎样实现的,
把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
x* p=new x;
p->func();
}
注意,这里主要改的是x* p=new x,建一个x对象,则由于func函数是一个虚函数,所在这里应该调用的是x的func而当func不是虚函数时,则调用base的func函数,虚函数和普通函数到底有什么区别?编译器又是怎么处理的?我们来作一个测式,写如下程序:
#include <iostream.h>
class X{
int i;
public:
a()
{
}
};
class Y{
int i;
public:
virtual a()
{
}
};
class Z{
int i;
public:
virtual a()
{
}
virtual b()
{
}
};
void main()
{
cout<<sizeof(X)<<endl;
cout<<sizeof(Y)<<endl;
cout<<sizeof(Z)<<endl;
}
这样我们可以得到三个类的大小,分别是:4,8,8类X与类Y的构构基本相同但Y的大小是X的两倍,而X与Y的不同点就是Y的a是一个虚函数,而Y与Z的大小是相同的,但Z有两个虚函数,而Y只是一个虚函数,得出这样的结果的原因是因为不带虚函数的对象的长度是单个int的长度,而带有单个虚函数的对象长度是不带虚函数的长度再加上一个指针的长度,实际是编译器在Y中插入了一个指针(VPTR),所以带一个虚函数和带两个虚函数没有区别,都只插入了一个指针,而这个指针指向一个存放函数地址的表(虚函数据表),这个表存放着具体函数。我们用函数图来画出函数的结构:
难点就在于虚函数表的内容是依据类中的虚函数声明次序,一一填入函数指针,子类会继承父类的虚函数表,当我们在改写子类时,虚函数表就受了影响:表中元素指的函数地址不再是父类的函数地址,而是子类的函数地址。所以当我们创建一个X对像的时候,编译器能知道执行的是X的func
我们再来看:base* p=new X
前面我们讲了这里是按照向上类型转换的原则把X转换成了base,而此时baser的VPTR指针会指向X的虚函数表,所以,p->func()会执行X的func函数.
这不是最新的文章,但绝对称得上经典,耐心看完后你会有所收获!
转自“蓝森林”网站
原作者迪-克斯莫(Roberto Di Cosmo)博士的网站
[译者按]本文是在法国互联网上流传很广的对微软的檄文,作者是计算机博士,现就职于法国巴黎第七大学计算机系。原文已经被翻译成英语、德语、西班牙语和意大利语,可以在http://www.pps.jussieu.fr/~dicosmo/找到。
一、引言
圣诞前期间,我再次被媒界铺天盖地的报道所震惊。“多媒体”、“万维网”、“互联网”这些时髦词汇及其派生物如雨后春笋充人耳目。在这些报纸、杂志和那些即兴“专家”眼里,您如果手里没有一台崭新的、价钱昂贵的、能把您带入那五彩缤纷的虚拟空间的计算机,您就不算是个幸福的人。
我们时刻都在听着一个永恒不变的教导:世界上只有一种计算机,它叫PC,当然一定是安装着Intel芯片的PC,而且世界上只存在一个必不可少的软件-微软生产的Window系列(大家干脆懒得去区分“操作系统”和“应用软件”这两个截然不同的名词,媒界所说的Window97实际上就是Window95捆绑上word、Excel等办公软件,被称为Office97的东西)。
更令人奇怪的还在后头,今天美国人已经开始从漫长的冬眠里觉醒,意识到这两个超级跨国公司的阴险嘴脸:它们利用自己的垄断地位,扼杀了无数产品性能远远高于自己的公司。而我们法国却厚颜无耻的在向这两个托拉斯献媚争宠。我佩服Ralph Nader(勇敢的站出来保护消费者的利益,令美国通用汽车公司撤回它们生产的不安全汽车),佩服美国司法部对微软的起诉,更佩服美国民众对此事的强烈反响:美国著名的亲微软的CNN电视台在网上做了民意测验,结果绝大多数网民支持司法部的举动,CNN竟然中止了此项调查,在无数网民的抗议下,不得不公布结果。
但是法国的民众还沉睡在微软那温柔的摇篮里,他们梦见一个仁慈的善者在向所有的学校乡村分发免费的Window95,真心实意的帮助法国弥补技术上的落后;他们微笑着看着天蓝色的屏幕上显示出一条条令人安心的信息,告诉用户某某环节某某过程引起了某某例外,当然这只是您自己的操作不当,不是Window的错误;他们在这美梦里从来不反问一下:一个比几十年前能把人类送上月球又安全送回来时所用的计算机还强劲几倍、几十倍的PC,被安装上微软的Office97以后,为什么不能正确的处理一本只有百来页的资料? 阅读全文
转自“蓝森林”网站
原作者迪-克斯莫(Roberto Di Cosmo)博士的网站
[译者按]本文是在法国互联网上流传很广的对微软的檄文,作者是计算机博士,现就职于法国巴黎第七大学计算机系。原文已经被翻译成英语、德语、西班牙语和意大利语,可以在http://www.pps.jussieu.fr/~dicosmo/找到。
一、引言
圣诞前期间,我再次被媒界铺天盖地的报道所震惊。“多媒体”、“万维网”、“互联网”这些时髦词汇及其派生物如雨后春笋充人耳目。在这些报纸、杂志和那些即兴“专家”眼里,您如果手里没有一台崭新的、价钱昂贵的、能把您带入那五彩缤纷的虚拟空间的计算机,您就不算是个幸福的人。
我们时刻都在听着一个永恒不变的教导:世界上只有一种计算机,它叫PC,当然一定是安装着Intel芯片的PC,而且世界上只存在一个必不可少的软件-微软生产的Window系列(大家干脆懒得去区分“操作系统”和“应用软件”这两个截然不同的名词,媒界所说的Window97实际上就是Window95捆绑上word、Excel等办公软件,被称为Office97的东西)。
更令人奇怪的还在后头,今天美国人已经开始从漫长的冬眠里觉醒,意识到这两个超级跨国公司的阴险嘴脸:它们利用自己的垄断地位,扼杀了无数产品性能远远高于自己的公司。而我们法国却厚颜无耻的在向这两个托拉斯献媚争宠。我佩服Ralph Nader(勇敢的站出来保护消费者的利益,令美国通用汽车公司撤回它们生产的不安全汽车),佩服美国司法部对微软的起诉,更佩服美国民众对此事的强烈反响:美国著名的亲微软的CNN电视台在网上做了民意测验,结果绝大多数网民支持司法部的举动,CNN竟然中止了此项调查,在无数网民的抗议下,不得不公布结果。
但是法国的民众还沉睡在微软那温柔的摇篮里,他们梦见一个仁慈的善者在向所有的学校乡村分发免费的Window95,真心实意的帮助法国弥补技术上的落后;他们微笑着看着天蓝色的屏幕上显示出一条条令人安心的信息,告诉用户某某环节某某过程引起了某某例外,当然这只是您自己的操作不当,不是Window的错误;他们在这美梦里从来不反问一下:一个比几十年前能把人类送上月球又安全送回来时所用的计算机还强劲几倍、几十倍的PC,被安装上微软的Office97以后,为什么不能正确的处理一本只有百来页的资料? 阅读全文
<?php
$year = $_REQUEST['year'];
$moth = $_REQUEST['moth'];
$title = "新浪互联星空播客每日运营报表";
$chword = iconv("UTF-8","GBK", $title);
$filename = $year.iconv("UTF-8","GBK", "年").$moth.iconv("UTF-8","GBK", "月").$day.$chword;
//$filename = $year."-".$moth;
header("Content-type:application/vnd.ms-excel");
//header("Content-Disposition:filename=test.xls");
header("Content-Disposition:filename=".$filename.".xls");
$title = "日期\tPV\tUIP\t注册用户数\t视频上传量\t视频播放量\t当日视频总量\t当日视频播放总时长\t\n";
echo iconv("UTF-8","GBK", $title); //由于php是utf8的编码,为此要转化为gbk到xsl中。。否则乱码
后面按照一定格式输出,比如用"\t"来分割各个字段。
while (!$rs->EOF)
{//遍历记录集
$result=array("day_key"=>$rs->fields['day_key'],"pv"=>$rs->fields['pv'],"uip"=>$rs->fields['uip'],"reg_member"=> $rs->fields['reg_member'],"upload_ct"=>$rs->fields['upload_ct'],"play_ct"=>$rs->fields['play_ct'],"video_total"=>$rs->fields['video_total'],"play_time"=>$rs->fields['play_time']);
//echo count($result);
foreach ($result as $value)
{
echo $value."\t";
}
echo "\n";
unset($result);
$rs->MoveNext();//将指针指到下一条记录,不用的话,会出现死循环!
}
$year = $_REQUEST['year'];
$moth = $_REQUEST['moth'];
$title = "新浪互联星空播客每日运营报表";
$chword = iconv("UTF-8","GBK", $title);
$filename = $year.iconv("UTF-8","GBK", "年").$moth.iconv("UTF-8","GBK", "月").$day.$chword;
//$filename = $year."-".$moth;
header("Content-type:application/vnd.ms-excel");
//header("Content-Disposition:filename=test.xls");
header("Content-Disposition:filename=".$filename.".xls");
$title = "日期\tPV\tUIP\t注册用户数\t视频上传量\t视频播放量\t当日视频总量\t当日视频播放总时长\t\n";
echo iconv("UTF-8","GBK", $title); //由于php是utf8的编码,为此要转化为gbk到xsl中。。否则乱码
后面按照一定格式输出,比如用"\t"来分割各个字段。
while (!$rs->EOF)
{//遍历记录集
$result=array("day_key"=>$rs->fields['day_key'],"pv"=>$rs->fields['pv'],"uip"=>$rs->fields['uip'],"reg_member"=> $rs->fields['reg_member'],"upload_ct"=>$rs->fields['upload_ct'],"play_ct"=>$rs->fields['play_ct'],"video_total"=>$rs->fields['video_total'],"play_time"=>$rs->fields['play_time']);
//echo count($result);
foreach ($result as $value)
{
echo $value."\t";
}
echo "\n";
unset($result);
$rs->MoveNext();//将指针指到下一条记录,不用的话,会出现死循环!
}
在编写php程序的时候,往往会出现对其post get 等的编码,于是就有对空格的处理,程序如下:
<?php
$file=file("D:\wwwroot\www\htdocs\sinanet.txt");
//$file=file("D:\wwwroot\www\htdocs\sinatest.txt");
$count=0;
$line=0;
for($i=0;$i<=count($file);$i++)
{
$line=$line+1;
echo $line."\n";
$result = explode("sinanet",$file[$i]);
for($j=0;$j<count($result);$j++)
{
if($result[$j])
{
$url="http://you.video.sina.com.cn/pg/search/iaskSearch.class.php?key=\"".urlencode($result[$j])."\"";
$judge=file_get_contents($url);
$judge_handle = strstr($judge,"抱歉");//专辑推荐
if($judge_handle)
{ $count=$count+1;
$rest = substr($judge_handle, 0, 14);
echo $rest;
echo "关键词:".$result[$j]."\n";
}else{
echo $url;
echo "\n关键词:".$result[$j]."可能没有出现抱歉***!"."\n";
}
}else{
echo "有问题:".$result[$j]."\n";
}
}
echo "\n";
}
echo "总共找到抱歉条目:".$count."分析文件".$line."行!";
?>
以上语句如果不用urlencode()来进行编码,往往容易出现问题,example:
<?php
$key = "Chinese Democracy";
$key = urlencode($key);
$url = "http://you.video.sina.com.cn/pg/search/iaskSearch.class.php?key=".$key;
$judge= file_get_contents($url);
echo $judge;
return;
$judge_handle = strstr($judge,"抱歉");//专辑推荐
if($judge_handle)
{
$count=$count+1;
$rest = substr($judge_handle, 0, 14);
echo $rest;
echo "关键词:".$result[$j]."\n";
}else{
echo $url;
echo "<br>关键词:".$result[$j]."可能没有出现抱歉***!"."\n";
}
?>
不加上urlencode会出现如下问题:$url = "http://you.video.sina.com.cn/pg/search/iaskSearch.class.php?key=’Chinese‘ 而不是:"Chinese Democracy",为此最好每次涉及到url的时候加上urlencode.
<?php
$file=file("D:\wwwroot\www\htdocs\sinanet.txt");
//$file=file("D:\wwwroot\www\htdocs\sinatest.txt");
$count=0;
$line=0;
for($i=0;$i<=count($file);$i++)
{
$line=$line+1;
echo $line."\n";
$result = explode("sinanet",$file[$i]);
for($j=0;$j<count($result);$j++)
{
if($result[$j])
{
$url="http://you.video.sina.com.cn/pg/search/iaskSearch.class.php?key=\"".urlencode($result[$j])."\"";
$judge=file_get_contents($url);
$judge_handle = strstr($judge,"抱歉");//专辑推荐
if($judge_handle)
{ $count=$count+1;
$rest = substr($judge_handle, 0, 14);
echo $rest;
echo "关键词:".$result[$j]."\n";
}else{
echo $url;
echo "\n关键词:".$result[$j]."可能没有出现抱歉***!"."\n";
}
}else{
echo "有问题:".$result[$j]."\n";
}
}
echo "\n";
}
echo "总共找到抱歉条目:".$count."分析文件".$line."行!";
?>
以上语句如果不用urlencode()来进行编码,往往容易出现问题,example:
<?php
$key = "Chinese Democracy";
$key = urlencode($key);
$url = "http://you.video.sina.com.cn/pg/search/iaskSearch.class.php?key=".$key;
$judge= file_get_contents($url);
echo $judge;
return;
$judge_handle = strstr($judge,"抱歉");//专辑推荐
if($judge_handle)
{
$count=$count+1;
$rest = substr($judge_handle, 0, 14);
echo $rest;
echo "关键词:".$result[$j]."\n";
}else{
echo $url;
echo "<br>关键词:".$result[$j]."可能没有出现抱歉***!"."\n";
}
?>
不加上urlencode会出现如下问题:$url = "http://you.video.sina.com.cn/pg/search/iaskSearch.class.php?key=’Chinese‘ 而不是:"Chinese Democracy",为此最好每次涉及到url的时候加上urlencode.
还是有关中文的问题。PHP内置的字符串长度函数strlen无法正确处理中文字符串,它得到的只是字符串所占的字节数。对于GB2312的中文编码,strlen得到的值是汉字个数的2倍,而对于UTF-8编码的中文,就是3倍的差异了(在UTF-8编码下,一个汉字占3个字节)。
采用mb_strlen函数可以较好地解决这个问题。mb_strlen的用法和strlen类似,只不过它有第二个可选参数用于指定字符编码。例如得到UTF-8的字符串$str长度,可以用mb_strlen($str,'UTF-8')。如果省略第二个参数,则会使用PHP的内部编码。内部编码可以通过mb_internal_encoding()函数得到。需要注意的是,mb_strlen并不是PHP核心函数,使用前需要确保在 php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函数的问题。
采用mb_strlen函数可以较好地解决这个问题。mb_strlen的用法和strlen类似,只不过它有第二个可选参数用于指定字符编码。例如得到UTF-8的字符串$str长度,可以用mb_strlen($str,'UTF-8')。如果省略第二个参数,则会使用PHP的内部编码。内部编码可以通过mb_internal_encoding()函数得到。需要注意的是,mb_strlen并不是PHP核心函数,使用前需要确保在 php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函数的问题。
1. 必须有一个圈子。无论如何做都是画地为牢:不加入一个圈子,就成为所有人的敌人;加入一个圈子,就成为另一个圈子的敌人;加入两个圈子,就等于没有加入圈子。只有孤独求败的精英才可完全避免圈子的困扰——这种人通常只有一个圈子,圈子里只站着老板一个人。
2. 必须争取成为第二名。名次与帮助你的人数成正比——如果是第一名,将因缺乏帮助而成为第二名;第二名永远是得道多助的位置,坏处是永远不能成为第一名。
3. 必须理解职责的定义。职责是你必须要做的工作,但办公室的生存定律是,职责就是你必须要做的工作之外的所有工作。
4. 必须参加每一场饭局。如果参加,你在饭局上的发言会变成流言;如果不参加,你的流言会变成饭局上的发言。
5. 必须懂得八卦定理。和一位以上的同事成为亲密朋友,你的所有缺点与隐私将在办公室内公开;和一位以下的同事成为亲密朋友,所有人都会对你的缺点与隐私感兴趣。
6. 必须明白加班是一种艺术。如果你在上班时间做事,会因为没有加班而被认为不够勤奋;如果你不在上班时间做事,你会被认为工作效率低下而不得不去加班。
7. 必须熟练接受批评的方法。面对上司的判断,认为你没错,你缺乏认识问题的能力;认为你错了,你没有解决问题的能力——接受错误的最好方式就是对错误避而不谈。最后一条,不许和老板谈公正。
8. 必须理解“难得糊涂”的词义。糊涂让你被人认为没有主见,不糊涂让你被人认为难以相处——“难得糊涂”在于糊涂的时机,什么时候糊涂取决于你不糊涂的程度。
9. 必须明白集体主义是一种选择。如果你不支持大部分人的决定,想法一定不会被通过;如果你支持大部分人的决定,将减少晋升机会——有能力的人总是站在集体的反面。
阅读全文
2. 必须争取成为第二名。名次与帮助你的人数成正比——如果是第一名,将因缺乏帮助而成为第二名;第二名永远是得道多助的位置,坏处是永远不能成为第一名。
3. 必须理解职责的定义。职责是你必须要做的工作,但办公室的生存定律是,职责就是你必须要做的工作之外的所有工作。
4. 必须参加每一场饭局。如果参加,你在饭局上的发言会变成流言;如果不参加,你的流言会变成饭局上的发言。
5. 必须懂得八卦定理。和一位以上的同事成为亲密朋友,你的所有缺点与隐私将在办公室内公开;和一位以下的同事成为亲密朋友,所有人都会对你的缺点与隐私感兴趣。
6. 必须明白加班是一种艺术。如果你在上班时间做事,会因为没有加班而被认为不够勤奋;如果你不在上班时间做事,你会被认为工作效率低下而不得不去加班。
7. 必须熟练接受批评的方法。面对上司的判断,认为你没错,你缺乏认识问题的能力;认为你错了,你没有解决问题的能力——接受错误的最好方式就是对错误避而不谈。最后一条,不许和老板谈公正。
8. 必须理解“难得糊涂”的词义。糊涂让你被人认为没有主见,不糊涂让你被人认为难以相处——“难得糊涂”在于糊涂的时机,什么时候糊涂取决于你不糊涂的程度。
9. 必须明白集体主义是一种选择。如果你不支持大部分人的决定,想法一定不会被通过;如果你支持大部分人的决定,将减少晋升机会——有能力的人总是站在集体的反面。
阅读全文
MySQL5.1地的确提供了好多有力的工具来帮助我们DBA进行数据库管理。
现在看一下这个压力测试工具mysqlslap.
关于他的选项手册上以及--help介绍的很详细。
我解释一下一些常用的选项。
这里要注意的几个选项:
--concurrency代表并发数量,多个可以用逗号隔开,当然你也可以用自己的分隔符隔开,这个时候要用到--delimiter开关。
--engines代表要测试的引擎,可以有多个,用分隔符隔开。
--iterations代表要运行这些测试多少次。
--auto-generate-sql 代表用系统自己生成的SQL脚本来测试。
--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
--number-of-queries 代表总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算。比如倒数第二个结果2=200/100。
--debug-info 代表要额外输出CPU以及内存的相关信息。
--number-int-cols 代表示例表中的INTEGER类型的属性有几个。
--number-char-cols 意思同上。
--create-schema 代表自己定义的模式(在MySQL中也就是库)。
--query 代表自己的SQL脚本。
--only-print 如果只想打印看看SQL语句是什么,可以用这个选项。
现在来看一些我测试的例子。
1、用自带的SQL脚本来测试。
MySQL版本为5.1.23
[root@localhost ~]# mysqlslap --defaults-file=/usr/local/mysql-maria/my.cnf --concurrency=50,100,200 --iterations=1 --number-int-cols=4 --number-char-cols=35 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=200 --debug-info -uroot -p1 -S/tmp/mysql_3310.sock
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 0.063 seconds
Minimum number of seconds to run all queries: 0.063 seconds
Maximum number of seconds to run all queries: 0.063 seconds
Number of clients running queries: 50
Average number of queries per client: 4
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 0.070 seconds
Minimum number of seconds to run all queries: 0.070 seconds
Maximum number of seconds to run all queries: 0.070 seconds
Number of clients running queries: 100
Average number of queries per client: 2
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 0.092 seconds
Minimum number of seconds to run all queries: 0.092 seconds
Maximum number of seconds to run all queries: 0.092 seconds
Number of clients running queries: 200
Average number of queries per client: 1
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 0.115 seconds
Minimum number of seconds to run all queries: 0.115 seconds
Maximum number of seconds to run all queries: 0.115 seconds
Number of clients running queries: 50
Average number of queries per client: 4
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 0.134 seconds
Minimum number of seconds to run all queries: 0.134 seconds
Maximum number of seconds to run all queries: 0.134 seconds
Number of clients running queries: 100
Average number of queries per client: 2
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 0.192 seconds
Minimum number of seconds to run all queries: 0.192 seconds
Maximum number of seconds to run all queries: 0.192 seconds
Number of clients running queries: 200
Average number of queries per client: 1
User time 0.06, System time 0.15
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 5803, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 8173, Involuntary context switches 528
我来解释一下结果的含义。
拿每个引擎最后一个Benchmark示例。
对于INNODB引擎,200个客户端同时运行这些SQL语句平均要花0.192秒。相应的MYISAM为0.092秒。
现在看一下这个压力测试工具mysqlslap.
关于他的选项手册上以及--help介绍的很详细。
我解释一下一些常用的选项。
这里要注意的几个选项:
--concurrency代表并发数量,多个可以用逗号隔开,当然你也可以用自己的分隔符隔开,这个时候要用到--delimiter开关。
--engines代表要测试的引擎,可以有多个,用分隔符隔开。
--iterations代表要运行这些测试多少次。
--auto-generate-sql 代表用系统自己生成的SQL脚本来测试。
--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
--number-of-queries 代表总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算。比如倒数第二个结果2=200/100。
--debug-info 代表要额外输出CPU以及内存的相关信息。
--number-int-cols 代表示例表中的INTEGER类型的属性有几个。
--number-char-cols 意思同上。
--create-schema 代表自己定义的模式(在MySQL中也就是库)。
--query 代表自己的SQL脚本。
--only-print 如果只想打印看看SQL语句是什么,可以用这个选项。
现在来看一些我测试的例子。
1、用自带的SQL脚本来测试。
MySQL版本为5.1.23
[root@localhost ~]# mysqlslap --defaults-file=/usr/local/mysql-maria/my.cnf --concurrency=50,100,200 --iterations=1 --number-int-cols=4 --number-char-cols=35 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=200 --debug-info -uroot -p1 -S/tmp/mysql_3310.sock
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 0.063 seconds
Minimum number of seconds to run all queries: 0.063 seconds
Maximum number of seconds to run all queries: 0.063 seconds
Number of clients running queries: 50
Average number of queries per client: 4
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 0.070 seconds
Minimum number of seconds to run all queries: 0.070 seconds
Maximum number of seconds to run all queries: 0.070 seconds
Number of clients running queries: 100
Average number of queries per client: 2
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 0.092 seconds
Minimum number of seconds to run all queries: 0.092 seconds
Maximum number of seconds to run all queries: 0.092 seconds
Number of clients running queries: 200
Average number of queries per client: 1
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 0.115 seconds
Minimum number of seconds to run all queries: 0.115 seconds
Maximum number of seconds to run all queries: 0.115 seconds
Number of clients running queries: 50
Average number of queries per client: 4
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 0.134 seconds
Minimum number of seconds to run all queries: 0.134 seconds
Maximum number of seconds to run all queries: 0.134 seconds
Number of clients running queries: 100
Average number of queries per client: 2
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 0.192 seconds
Minimum number of seconds to run all queries: 0.192 seconds
Maximum number of seconds to run all queries: 0.192 seconds
Number of clients running queries: 200
Average number of queries per client: 1
User time 0.06, System time 0.15
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 5803, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 8173, Involuntary context switches 528
我来解释一下结果的含义。
拿每个引擎最后一个Benchmark示例。
对于INNODB引擎,200个客户端同时运行这些SQL语句平均要花0.192秒。相应的MYISAM为0.092秒。
一直在寻找一个完美的IDE统一体,可以统一完成所有PHP,javascript,css,html的编辑。
我一直在尝试,试过zend studio,editplus,ultraeditor,DW,始终无法在一个编辑器里完成所有的操作,怎样都会少那么一点支持。
终于!在zend studio for eclipse 出来之后我看到了希望,就是因为eclipse传说是个强大的插线板!
首次接触eclipse,经过几天的尝试,终于为这个插线板插上了完善的功能了。
1.PHP相关的所有功能zend studio for eclipse已经完善地提供了,只是用惯了zend studio 5.5的话会有点不习惯,咋说也要适应一下eclipse的习惯。
2.最难解决的是js和css的相关支持,特别是js,实在是让广大开发人员头痛的东西。用了几年的ultraeditor+alert()的编辑调试终于受不了了,于是一直在找一个完美一点的js编辑器,
【ultraeditor,editplus】之类的文本编辑器确实可以提供很快速的编辑,但是代码提示辅助实在不足,调试就更加不用说了,一句句alert()。
【Dreamweaver】也是很多人使用的,但这东西很明显不是专门为写js设计的,写css倒是很完美,对js基本只是提供了代码高亮而已
【1st javascript editor,Antechinus JavaScript Editor v9】这2个js编辑器可以说已经非常完善了,强大的代码提示,代码库辅助等功能,完全是为js而存在的。可惜的是这2者对中文的支持实在让人无奈,因为这2者都是不支持utf-8编码的文档的,所有utf-8编码的文档中的中文都只能看到乱码,只认gb2312 。没办法只能继续寻找。
【aptana】一个新兴的基于eclipse的插件,可以说这个插件已经完美地解决了js,css,html的编写了,加上强大的调试功能(非pro版的只支持firefox的调试,不知又没破解,pro版的就可以支持IE调试),唯一的缺点就是慢!没办法,基于eclipse的东西,至少准备200m 的空闲内存,通常是能吃掉200~300m的。
好!现在的问题就是在zend studio for eclipse 上插上aptana就完美啦
1.装好zend studio for eclipse,网上已经有完美的破解了
2.下载aptana的插件版:http://update.aptana.com/update/studio/3.2/ ,Download Plugin Update Site ,下载下来的zip文件不用解压。
3.插上:打开zend studio for eclipse,help->software updates->find and install...
选search for new features to install,next,New Archived site,选刚才下载的zip文件···之后就一步步next,accept的下去就是了。重启之后就完成了aptana的安装了
4.其实这样安装好之后还没没完成的,编辑起来无论是PHP还是HTML代码,都还是默认由zend来管理的,aptana还没能管事。(其实zend studio for eclipse已经可以比较好地支持js的代码提示了,当然没aptana强啦,还有就是不支持不支持css)。
5.最关键的一步就是让aptana来管理全部的*.html,*.js,*.css文件。
window->preferences->General->Editors->File Associations。就是在这页设置文件相关编辑器的,只要在这里设置
*.html,*.js,*.css的Association editors为aptan就可以(设置成Default)。
好了,现在又有一个问题,如果您是使用一些php框架,例如fleaphp,cakephp之类的,或者是smarty之类的,会有可能使用后缀比较特别的template文件,view文件。
例如cakephp使用的是*.thtml,当然这些文件后缀的使用是可以改变的(cakephp改起来比较不方便,而且可能会影响框架某些功能的使用,这个问题我在cakephp的官方论坛问过,大家都是建议改变编辑器的设置来支持*.thtml),而改变文件的支持就是在上面说的那页文件相关编辑器(File Associations)里面自己添加设置啦。
aptan新版本还可以支持php,我没有详细测试其功能,试了一下,代码提示的功能还是比较完善的,如果只使用代码提示功能还是可以代替一下zend studio的哦。
aptana的php插件:http://update.aptana.com/update/php/3.2/
安装方法跟aptana的安装一样,但是很如果装进去zend studio里很可能会抢掉zend的功能哦!反正我插进去后在*.thtml
文件里面无法使用···这点有待研究
写了这么多,算是对这几天的寻找做了总结吧,总结一下相关的关键点:
1.aptana,http://update.aptana.com/update/studio/3.2/
2.aptana的php插件:http://update.aptana.com/update/php/3.2/
3.eclipse文件相关编辑器设置:
window->preferences->General->Editors->File Associations。就是在这页设置文件相关编辑器的
4.模板文件特殊后缀的支持:文件相关编辑器(File Associations)
还要扩展一下 bugfree 和 project 提供 web浏览器给 eclipse也许是个解决方案。
开辟一个论坛 讨论开发工具集成方案 和 部署服务方案 以及 各种工具的优化应用模式 还有 好的项目管理模式以及开发模式。
zendeclipse 直接将 apatan下的plugins features拷贝到 zendeclipse下就可以在zend下开启apatan的相关功能,再将apatan安装一遍,对任意文件进行调试,aptana会提示要安装 firebug插件,同意。安装后卸载apatan。这样就可以使用 apatan的firebug了。需要注意的是调试前要开启firefox
注意软件版本号 Zend Studio for Eclipse - 6.0.0
apatan 1.1
我一直在尝试,试过zend studio,editplus,ultraeditor,DW,始终无法在一个编辑器里完成所有的操作,怎样都会少那么一点支持。
终于!在zend studio for eclipse 出来之后我看到了希望,就是因为eclipse传说是个强大的插线板!
首次接触eclipse,经过几天的尝试,终于为这个插线板插上了完善的功能了。
1.PHP相关的所有功能zend studio for eclipse已经完善地提供了,只是用惯了zend studio 5.5的话会有点不习惯,咋说也要适应一下eclipse的习惯。
2.最难解决的是js和css的相关支持,特别是js,实在是让广大开发人员头痛的东西。用了几年的ultraeditor+alert()的编辑调试终于受不了了,于是一直在找一个完美一点的js编辑器,
【ultraeditor,editplus】之类的文本编辑器确实可以提供很快速的编辑,但是代码提示辅助实在不足,调试就更加不用说了,一句句alert()。
【Dreamweaver】也是很多人使用的,但这东西很明显不是专门为写js设计的,写css倒是很完美,对js基本只是提供了代码高亮而已
【1st javascript editor,Antechinus JavaScript Editor v9】这2个js编辑器可以说已经非常完善了,强大的代码提示,代码库辅助等功能,完全是为js而存在的。可惜的是这2者对中文的支持实在让人无奈,因为这2者都是不支持utf-8编码的文档的,所有utf-8编码的文档中的中文都只能看到乱码,只认gb2312 。没办法只能继续寻找。
【aptana】一个新兴的基于eclipse的插件,可以说这个插件已经完美地解决了js,css,html的编写了,加上强大的调试功能(非pro版的只支持firefox的调试,不知又没破解,pro版的就可以支持IE调试),唯一的缺点就是慢!没办法,基于eclipse的东西,至少准备200m 的空闲内存,通常是能吃掉200~300m的。
好!现在的问题就是在zend studio for eclipse 上插上aptana就完美啦
1.装好zend studio for eclipse,网上已经有完美的破解了
2.下载aptana的插件版:http://update.aptana.com/update/studio/3.2/ ,Download Plugin Update Site ,下载下来的zip文件不用解压。
3.插上:打开zend studio for eclipse,help->software updates->find and install...
选search for new features to install,next,New Archived site,选刚才下载的zip文件···之后就一步步next,accept的下去就是了。重启之后就完成了aptana的安装了
4.其实这样安装好之后还没没完成的,编辑起来无论是PHP还是HTML代码,都还是默认由zend来管理的,aptana还没能管事。(其实zend studio for eclipse已经可以比较好地支持js的代码提示了,当然没aptana强啦,还有就是不支持不支持css)。
5.最关键的一步就是让aptana来管理全部的*.html,*.js,*.css文件。
window->preferences->General->Editors->File Associations。就是在这页设置文件相关编辑器的,只要在这里设置
*.html,*.js,*.css的Association editors为aptan就可以(设置成Default)。
好了,现在又有一个问题,如果您是使用一些php框架,例如fleaphp,cakephp之类的,或者是smarty之类的,会有可能使用后缀比较特别的template文件,view文件。
例如cakephp使用的是*.thtml,当然这些文件后缀的使用是可以改变的(cakephp改起来比较不方便,而且可能会影响框架某些功能的使用,这个问题我在cakephp的官方论坛问过,大家都是建议改变编辑器的设置来支持*.thtml),而改变文件的支持就是在上面说的那页文件相关编辑器(File Associations)里面自己添加设置啦。
aptan新版本还可以支持php,我没有详细测试其功能,试了一下,代码提示的功能还是比较完善的,如果只使用代码提示功能还是可以代替一下zend studio的哦。
aptana的php插件:http://update.aptana.com/update/php/3.2/
安装方法跟aptana的安装一样,但是很如果装进去zend studio里很可能会抢掉zend的功能哦!反正我插进去后在*.thtml
文件里面无法使用···这点有待研究
写了这么多,算是对这几天的寻找做了总结吧,总结一下相关的关键点:
1.aptana,http://update.aptana.com/update/studio/3.2/
2.aptana的php插件:http://update.aptana.com/update/php/3.2/
3.eclipse文件相关编辑器设置:
window->preferences->General->Editors->File Associations。就是在这页设置文件相关编辑器的
4.模板文件特殊后缀的支持:文件相关编辑器(File Associations)
还要扩展一下 bugfree 和 project 提供 web浏览器给 eclipse也许是个解决方案。
开辟一个论坛 讨论开发工具集成方案 和 部署服务方案 以及 各种工具的优化应用模式 还有 好的项目管理模式以及开发模式。
zendeclipse 直接将 apatan下的plugins features拷贝到 zendeclipse下就可以在zend下开启apatan的相关功能,再将apatan安装一遍,对任意文件进行调试,aptana会提示要安装 firebug插件,同意。安装后卸载apatan。这样就可以使用 apatan的firebug了。需要注意的是调试前要开启firefox
注意软件版本号 Zend Studio for Eclipse - 6.0.0
apatan 1.1
提起运算符的优先级,很多了解C++的过来人都会想:这有什么难的?不就是谁的优先级高就算谁么。确实如此,运算符的优先级不是一个大问题,但对于一个初学者来说,却经常轻易在上面迷糊与犯错。而对于一个了解C++的人来说,我相信也会偶然在上面摔倒,不信就继续往下读。
“优先级高的先运算”带来的困惑
C++中运算符的优先级有一张表,表里把运算符进行了分类,这张表是不需要死记硬背的,只要有个大致的轮廓就OK了。例如应该记住最低优先级是逗号运算符,其次是赋值运算符,再其次是三目运算符。而关系运算符的优先级高于逻辑运算符(不包括逻辑非运算),算术运算符的优先级高于关系运算符,象++和﹣﹣的优先级比前面几个都高,但最高的要属()了。知道这些后,你的脑海里一定有一条准则了:优先级高的先运算。那么下面看一个例子:
int x=1,y=0;
!x&&x+y&++y;
上面的语句中出现了!、&& 、+、++这四个运算符,那么问题来了,到底先算谁呢?
有一个姓蔡的同学站起来说,++运算符在这里面优先级最高,理所应当最先算++,既先计算++y,再算!x,再算x+y,最后把它们&&起来。按照蔡同学的思路,第二步的结果是0&&x+y&&1,由于&&是严格运算,有一个为0结果既为0,所以不需要计算x+y了,整个语句的结果是:假。按照上面蔡同学的说法,执行完后y的值应该是1了,这对不对呢?
一位姓高的同学站起来反驳道,我觉得应该先计算!x,假如值为假,则不需要计算下去,最后结果为假。假如值为真,再计算x+y,同理假如其值为真,再去计算++y,否则最后结果也为假。
蔡同学不服起来说,高同学你觉得++和!谁的优先级高呢?高同学答道,那当然是++高。蔡同学接着问,那为什么还要先计算!呢?高同学答不出来了。
是呀,为什么要先算呢? 三层交换技术 交换机与路由器密码恢复 交换机的选购 路由器设置专题 路由故障处理手册 数字化校园网解决方案 加括号确定优先级的方法
高同学说的是正确的,为什么呢?下面我给大家解释一下。当多个优先级不同的运算符在一起时,为了不混淆,可以先加上括号,这样就分出层次了,相同层次的考虑结合性问题,当确定下来先算那块时,再往这块里面深入。例如上面的例子,我们可以这样加上括号:从左向右看,由于!比&&优先级高,所以有(!x),又由于&&比+优先级低,所以有(x+y),而++优先级高于&&,所以(++y)。这样整个式子就变成了:(!x)&&(x+y)&&(++y),最外层的是两个&&运算,由于&&的结合性是从左至右,所以上式可看成:A&&B&&C,先计算A,再计算B,最后算C。由于x=1,则!x就为假,后面的就不需要再算了,整个语句的值为假。执行完后,y的值没变,还是0。
所以碰到不清楚先算谁后算谁时,先加个括号看看,就明白了先后次序。下面做一个加括号的练习:给语句c=a>b?a:b;加括号。此语句有三个运算符:=、>、? :,应该怎样加括号呢?
第一种方案:c=((a>b)?a:b);
第二种方案:c=(a>(b?a:b));
第三种方案:(c=a)>(b?a:b);
应该是那一种呢?按照运算符优先级的高低顺序,>优先级高于=,所以不可能把(c=a)括起来。而>优先级高于? :运算符。所以也不可能把(b?a:b)括起来。因此,第一种答案正确。
下面再看一个类似的例子:
int i=8,j=4,k;
k=i
猛然一看,有些人上来可能就要计算++i和++j了。这里不妨先加括号看看。从左至右看,<的优先级高于=而且又高于? :,所以有k=(i
所以运算符的优先级千万要小心,既不是想象的那么难,也不是想象的那么轻易。
“优先级高的先运算”带来的困惑
C++中运算符的优先级有一张表,表里把运算符进行了分类,这张表是不需要死记硬背的,只要有个大致的轮廓就OK了。例如应该记住最低优先级是逗号运算符,其次是赋值运算符,再其次是三目运算符。而关系运算符的优先级高于逻辑运算符(不包括逻辑非运算),算术运算符的优先级高于关系运算符,象++和﹣﹣的优先级比前面几个都高,但最高的要属()了。知道这些后,你的脑海里一定有一条准则了:优先级高的先运算。那么下面看一个例子:
int x=1,y=0;
!x&&x+y&++y;
上面的语句中出现了!、&& 、+、++这四个运算符,那么问题来了,到底先算谁呢?
有一个姓蔡的同学站起来说,++运算符在这里面优先级最高,理所应当最先算++,既先计算++y,再算!x,再算x+y,最后把它们&&起来。按照蔡同学的思路,第二步的结果是0&&x+y&&1,由于&&是严格运算,有一个为0结果既为0,所以不需要计算x+y了,整个语句的结果是:假。按照上面蔡同学的说法,执行完后y的值应该是1了,这对不对呢?
一位姓高的同学站起来反驳道,我觉得应该先计算!x,假如值为假,则不需要计算下去,最后结果为假。假如值为真,再计算x+y,同理假如其值为真,再去计算++y,否则最后结果也为假。
蔡同学不服起来说,高同学你觉得++和!谁的优先级高呢?高同学答道,那当然是++高。蔡同学接着问,那为什么还要先计算!呢?高同学答不出来了。
是呀,为什么要先算呢? 三层交换技术 交换机与路由器密码恢复 交换机的选购 路由器设置专题 路由故障处理手册 数字化校园网解决方案 加括号确定优先级的方法
高同学说的是正确的,为什么呢?下面我给大家解释一下。当多个优先级不同的运算符在一起时,为了不混淆,可以先加上括号,这样就分出层次了,相同层次的考虑结合性问题,当确定下来先算那块时,再往这块里面深入。例如上面的例子,我们可以这样加上括号:从左向右看,由于!比&&优先级高,所以有(!x),又由于&&比+优先级低,所以有(x+y),而++优先级高于&&,所以(++y)。这样整个式子就变成了:(!x)&&(x+y)&&(++y),最外层的是两个&&运算,由于&&的结合性是从左至右,所以上式可看成:A&&B&&C,先计算A,再计算B,最后算C。由于x=1,则!x就为假,后面的就不需要再算了,整个语句的值为假。执行完后,y的值没变,还是0。
所以碰到不清楚先算谁后算谁时,先加个括号看看,就明白了先后次序。下面做一个加括号的练习:给语句c=a>b?a:b;加括号。此语句有三个运算符:=、>、? :,应该怎样加括号呢?
第一种方案:c=((a>b)?a:b);
第二种方案:c=(a>(b?a:b));
第三种方案:(c=a)>(b?a:b);
应该是那一种呢?按照运算符优先级的高低顺序,>优先级高于=,所以不可能把(c=a)括起来。而>优先级高于? :运算符。所以也不可能把(b?a:b)括起来。因此,第一种答案正确。
下面再看一个类似的例子:
int i=8,j=4,k;
k=i
猛然一看,有些人上来可能就要计算++i和++j了。这里不妨先加括号看看。从左至右看,<的优先级高于=而且又高于? :,所以有k=(i
所以运算符的优先级千万要小心,既不是想象的那么难,也不是想象的那么轻易。
快下班了,写点鉴赏的东西:
歌曲名称:千年之恋
歌手名称:信乐团
谁在悬崖沏一壶茶 我个人觉得应该修改为心在悬崖沏一壶茶,谁不能代表谁,而心更加能说明人的主观性和浪漫的情感。
温热前世的牵挂 谁又愿意不相信前世,更加主主观,人们往往喜欢,就像我宁愿相信主一样,尽管我是学物理的:)
而我在调整千年的时差 为何要调整时差呢?是恨和爱的铰接,还是对离得太远的恋人们的一种对互相的期盼吗?
爱恨全喝下 这一步说明还很年轻,爱河的水还浅,喝光了看似自己看透的爱和恨。
岁月在岩石上敲打 时间在恋人们的慢慢的走过。
我又留长了头发 又字,体现了一个人对一种状态的回归,长:说明了痴情不改、
耐心等待海岸线的变化 已经死了心的他或她已经高度成熟?应该仅仅还是一种境界的提升罢了。
大雨就要下 对心境的描述,但为何用大雨来寄托。
风 狠狠的刮 风,本来无情,为何用了人类的狠狠来表态呢?更进一步。
谁 在害怕 这句话,却反倒道出了人的狠心。
海风一直眷恋着沙 说明本来我们该在一起,很是眷恋的一种唯美情感表达。
你却错过我的年华 错过了,路过了,就像死了心还在的感觉。
错过我新长的枝丫 为何会新长呢?说的是有些时候当时没有抓住哦,而自己一直在改变,而来不及了的一种深刻的埋怨,极度的嫉狠。
和我的白发
蝴蝶依旧狂恋着花 自然现象,赋 比 兴 中兴的手法,Next(蝶恋花)
你却错过我的年华
错过我转世的脸颊 任然相信,但人已经各有主了吧,估计!
你还爱我吗 呵呵,心软了
我等你一句话 这句话,是爱恨的焦点,全局。
一生行走望断天崖 泪水已经已经盲目了。。。。。下句全是。。。
最远不过是晚霞
而你今生又在哪户人家
欲语泪先下
沙滩上消失的浪花
让我慢慢想起家
曾经许下的永远又在哪
总是放不下
啊 轮回的记忆在风化
我将它牢牢记下
海风一直眷恋着沙
你却错过我的年华
错过我新长的枝丫
和我的白发
蝴蝶依旧狂恋着花
你却错过我的年华
错过我转世的脸颊
你还爱我吗
我等你一句话
蝴蝶依旧狂恋着花
你却错过我的年华
错过我转世的脸颊
你还爱我吗
我等你一句话
歌曲名称:千年之恋
歌手名称:信乐团
谁在悬崖沏一壶茶 我个人觉得应该修改为心在悬崖沏一壶茶,谁不能代表谁,而心更加能说明人的主观性和浪漫的情感。
温热前世的牵挂 谁又愿意不相信前世,更加主主观,人们往往喜欢,就像我宁愿相信主一样,尽管我是学物理的:)
而我在调整千年的时差 为何要调整时差呢?是恨和爱的铰接,还是对离得太远的恋人们的一种对互相的期盼吗?
爱恨全喝下 这一步说明还很年轻,爱河的水还浅,喝光了看似自己看透的爱和恨。
岁月在岩石上敲打 时间在恋人们的慢慢的走过。
我又留长了头发 又字,体现了一个人对一种状态的回归,长:说明了痴情不改、
耐心等待海岸线的变化 已经死了心的他或她已经高度成熟?应该仅仅还是一种境界的提升罢了。
大雨就要下 对心境的描述,但为何用大雨来寄托。
风 狠狠的刮 风,本来无情,为何用了人类的狠狠来表态呢?更进一步。
谁 在害怕 这句话,却反倒道出了人的狠心。
海风一直眷恋着沙 说明本来我们该在一起,很是眷恋的一种唯美情感表达。
你却错过我的年华 错过了,路过了,就像死了心还在的感觉。
错过我新长的枝丫 为何会新长呢?说的是有些时候当时没有抓住哦,而自己一直在改变,而来不及了的一种深刻的埋怨,极度的嫉狠。
和我的白发
蝴蝶依旧狂恋着花 自然现象,赋 比 兴 中兴的手法,Next(蝶恋花)
你却错过我的年华
错过我转世的脸颊 任然相信,但人已经各有主了吧,估计!
你还爱我吗 呵呵,心软了
我等你一句话 这句话,是爱恨的焦点,全局。
一生行走望断天崖 泪水已经已经盲目了。。。。。下句全是。。。
最远不过是晚霞
而你今生又在哪户人家
欲语泪先下
沙滩上消失的浪花
让我慢慢想起家
曾经许下的永远又在哪
总是放不下
啊 轮回的记忆在风化
我将它牢牢记下
海风一直眷恋着沙
你却错过我的年华
错过我新长的枝丫
和我的白发
蝴蝶依旧狂恋着花
你却错过我的年华
错过我转世的脸颊
你还爱我吗
我等你一句话
蝴蝶依旧狂恋着花
你却错过我的年华
错过我转世的脸颊
你还爱我吗
我等你一句话