函数调用所采用的虚实结合在传值方面是有缺陷的.单向的"值传递"方式,只能从实参向形参传递数据,形参值的改变无法回传给实参!恩,这在某种情况下让人着实无法忍受.
今儿终于捡到个大宝贝把问题搞定了,高兴哈!指针,你这沟通方面的天才!给正郁闷着的叨咕下先.
[指针作为函数参数时,当然也不会改变实参指针变量的值,但可以改变实参指针变量所指向变量的值.]这就是解决问题的关键.
进一步解释哈,函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作函数参数,就可以通过指针变量改变主调函数中变量的值,相当于通过函数调用从被调用的函数中得到多个值.如果不用指针变量,我们就很难做到这一点.
举正反两个简单的例子来介绍具体实现方法.先让大家看个危机四伏却很正确的:
#include
using namespace std;
int main( )
{ void swap(int *p1,int *p2); //函数声明
int *pointer_1,*pointer_2,a,b; //定义指针变量pointer_1,pointer_2,整型变量a,b
cin>>a>>b;
pointer_1=&a; //使pointer_1指向a
pointer_2=&b; //使pointer_2指向b
if(a不要将main函数中的swap函数调用写成 if(a
using namespace std;
int main( )
{ void swap(int *p1,int *p2); //函数声明
int *pointer_1,*pointer_2,a,b; //定义指针变量pointer_1,pointer_2,整型变量a,b
cin>>a>>b;
pointer_1=&a; //使pointer_1指向a
pointer_2=&b; //使pointer_2指向b
if(a
2006年5月9日
#
下面是一个更加复杂的文件上传实例,先看该程序的代码,稍后我们将详细讲解这个程序.该程序命名为upload.php,代码如下:
if(!$UploadAction):
?>
文件上传界面
else:
?>
文件上传代码
$UploadAction=0;
echo "Good!";
$TimeLimit=60;/*设置超时限制时间 默认时间为30秒 设置为0时为不限时*/
set_time_limit($TimeLimit);
If(($UploadFile !="none"))
{
$UploadPath=AddSlashes(dirname($PATH_TRANSLATED))."\\upload\\";
//上传文件存放路径
$FileName=$UploadPath.$UploadFile_name;//上传文件名
if($UploadFile_size < 1024) //上传文件大小
{
$FileSize=(string)$UploadFile_size." 字节";
}
elseif ($UploadFile_size < (1024 * 1024))
{
$FileSize=number_format((double)($UploadFile_size/1024),1)." KB";
}
else{
$FileSize=number_format((double) ($UploadFile_size / (1024 * 1024)).
1) . " KB";
}
if(!file_exists($FileName))
{
if(copy($UploadFile,$FileName))
{ echo "文件 $UploadFile_name ($FileSize)上传成功! ";}
else
{ echo "文件 $UploadFile_name 上传失败! "; }
unlink ($UploadFile);
}
else
{ echo "文件" $UploadFile_name 已经存在! "; }
}
else
{ echo "你没有选择任何文件上传! ";}
set_time_limit(30); //恢复默认超时设置
?>
返回
endif;
?>
该程序首先生成一个简单的上传文件截面,浏览文件,单击[上传]按钮后,将显示上传成功页面.
下面详解释上面的程序.
本程序由于同时包含上传界面和上传处理部分,故总体上可以分为两部分,我们通过在form中添加UploadAction指出当前的状态(界面或实现). if(!$UploadAction):后是一部分,else;后又是一部分.前一部分是生成上传文件界面,后一部分是处理上传文件.
首先在form表单中要将method属性设为Post,enctype属性设为multipart/form-data;
在form表单中可以加一个hidden类型的input框,其中名字为MAX_FILE_SIZE的隐藏值域,通过设置其VALUE可以限制上传文件的大小.
因为form传递过来的值会自动赋值给同名变量,所以直接通过$UploadFile 可以直接访问上传的文件,但由于这是一个保存文件的变量,因此文件名字必须通过另外一个$UploadFile_name变量取得.
上传的文件必须用一个固定的目录保存,在这里我们用一个$UploadPath 变量保存.如可以设置$UploadPath ="/home/flier/upload/",这里我们使用了复杂一点的自动定位,如:
$UploadPath=AddSlashes(dirname($PATH_TRANSLATED))."\\upload\\";
$PATH_TRANSLATED,顾名思义就是当前传送目录,我们假定以其一个名为upload的子目录来保存上传的文件.dirname函数返回其目录名,然后加上子目录名.
然后用一个变量$FileName保存完整的上传后文件名和路径:
$FileName=$UploadPath.$UploadFile_name;
在前面的form表单中定义了一个变量UploadFile,在后面处理上传文件时,我们就可以使用这个变量,直接通过$UploadFile访问上传的文件,但由于这是一个保存文件的变量,因此文件名字必须通过另外一个$UploadFile_name变量取得.
下面是这个变量的具体用法:
1.$UploadFile:在将要存放上传文件的服务器上的临时文件名
2.$UploadFile_name:在发送者系统中的初始文件名.
3.$UploadFile_size:按字节计算的上传文件的大小.
4.$UploadFile_type:多用途网际邮件扩充协议类型的文件,前提是浏览器提供这种信息,比如说"image/gif".
用set_time_limit($TimeLimit);设置超时限制时间,默认时间为30秒,设置为0时为不限时,考虑到大文件上传时容易出现超时的情况,这里加大超时限制时间.
上面我们就详细讲述了如何使用PHP进行上传.这里要重点强调两点:
A.在form表单中要将method属性设为post,enctype属性设为multipart/form-data.
B.在form表单中可以加一个hidden类型的input框,其中名字为MAX_FILE_SIZE的隐藏值域,通过设置其VALUE可以限制上传文件的大小.当然,这个值不可能超过PHP的配置文件(PHP3.0为php3.ini,PHP4.0为php.ini)中的upload_max_filesize,注意这个input框一定要放在所有file类型的input框前面,否则也是无效的.
工作后就很少有兴趣写些技术层面的东西,作为补充,只在水缸博客(http://shuigang.bokenw.com)中发些神经而已.恩,犹豫了很久,是否应该在C++博客上搞点PHP,即网站开发所用到的经典事例,而后还是觉得写在这里合适些.私人生活和工作应该完全分开,这么做很有必要!
下面我们来说点正事.
首先,利用PHP的确可以实现文件的上传功能.(客户端的浏览器应该是Netscape 3以上或者IE 3以上的版本)
开工之前我们需要将PHP配置文件(PHP3.0为php3.ini,PHP4.0为php.ini)做如下设置:
将;upload_tmp_dir该行的注释符(即前面的分号)去掉,使该行在php.ini文档中起作用.upload_tmp_dir是用来定义上传文件的存放的临时路径,在这里还可以给其定义一个绝对路径,例如:upload_tmp_dir=d:\upload.当然,此时你的d:\upload目录必须有读写权限.
如果在.php程序里已经定义了上传的路径,此时上传文件的路径以.php程序里定义的路径为基准.
upload_max_filesize是用来限制PHP处理上传文件大小的最大值,以字节计算,默认值为2097152=2*1024*1024字节(2M),可通过修改默认值来定义最大上传文件的大小.
修改后不要忘了重启Apache、IIS或PWS服务器.
在PHP文件上传中,最重要的就是文件系统函数copy()的使用.
boolean copy(string source,string target)
说明如下:1.该函数用于文件的拷贝,同主机或跨系统均可.
2.参数source:源文件地址,在实际开发中可用form中的file组件来传递.
3.参数target:目标文件地址,但你必须拥有该目录的写文件权限,这在某些免费主页空间中是不可能的.
4.返回值为布尔值,成功为1,失败为0.
下面是一个最简单的文件上传实例,命名为simple_upload.phop,代码如下:
文件上传
该例首先是一个简单的上传网页界面,然后通过submit按钮判断是否已提交,如果已提交则进行上传处理,上传目录要有写权限.
2006年2月17日
#
<中文版>
C++现在可以作为高级语言来讲授了.也就是说,重点一开始就可以放在算法和容器上,而不是用在什么位呀,联合呀,C风格字符串,数组等东西上纠缠不清了.自然,底层的概念(如数组\重要的指针应用和强制转换)最终还是要教要学的.但是,可以等到作为新手的C++程序员\读者或学生已经成熟,能够在实现这些功能的高级概念的大背景中看待它们的时候,再对这些功能进行阐述.
我想特别强调(怎么强调都不过分)的是,应该多使用静态类型安全的字符串和容器,而不要学那些使用大量宏\强制转换和数组的编程风格.其实,可以根本不用宏,并且只在很少的非用不可的情况下才使用强制转换.我认为C\C++形式的宏是一种严重的缺陷--现在因为有了模板\名字空间\在线函数和常量这些正确的语言功能,它很大程度上更是一种多余了.同样,在任何语言中,强制转换的大量使用都是设计不良的标志.宏和强制转换是错误的主要渊源.不用她们也能工作,这一点大大提高了C++编程的安全性和优雅性.
标准C++改变了我们使用C++编程\设计程序以及教授C++编程的方式.这些变化不可能"毕其功于一役".我鼓励你在标准C++的编程方式上好好下一番功夫.我想脱胎换骨是有可能的.但是别太死心眼了.奇迹是不存在的,在产品代码中使用仅仅一知半解的语言功能和技术是相当危险的.现在该开始探索,开始试验了--标准C++真正对你有裨益的地方,就在理解新概念和新技术的旅程中!
旅途愉快!
Bjarne Stroustrup
<特别版>
去编程就是去理解.
--Kristen Nyggard
<第2版>
前路漫漫.
--Bilbo Baggins
<第1版>
语言磨砺了我们思维的方式,也决定着我们思考的范围.
--B.L.Whorf
"……而你,马库斯,你已经给了我许多东西;现在我要给你这个极好的忠告。做一个普通的人。放弃总是扮演马库斯.克可查的哪个游戏.你为马库斯.克可查操心操得太多了,以致你已经变成了他的奴隶和囚徒.你在做任何事情之前都要首先考虑它将如何影响马库斯.克可查的幸福和声望.你总是非常害怕马库斯可能会做一点愚蠢的事,或者令人讨厌的事。这些真的那么有意义吗?整个世界的人都在做蠢事……我真心希望你能轻松一点,让你那小小的心回到轻松的状态。你必须从现在开始,去做不止一个人,做许许多多的人们,就像你可能想到的那么多……
--卡伦.布利克森
("梦想者",出自"七个哥特人的传说",
笔名伊萨克.迪尼森,
Random House lnc.
版权所有,lsak Dinesen,1934年,1961年修订)
2006年2月6日
#
为使电文保密,往往按一定规律将电文转化成密码,收报人再按约定的规律将其译回原文.例如,可以按以下规律将电文变成密码:将字母A变成字母E,a变成e,即变成其后的第4个字母,W变成A,X变成B,Y变成C,Z变成D.字母按上述规律转换,非字母字符不变.如"Wonderful!"转换为"Asrhivjyp!".输入一行字符,要求输出其相应的密码.
先分析解题思路:转换的规律是将原来的字符c加4,就得到密码字符的ASCII代码.可用c=c+4来处理.但是还要对w,x,y,z(包括大小写)这4个字母作专门处理,使它们变为大小写的a,b,c,d.方法是如果执行完c=c+4后,c的新值已大于z(或Z),则表示原来的字母在v(或V)之后,应将它转换为a~d(或A~D).办法是使c减26.
程序如下:
#include
using namespace std;
int main( )
{char c;
while ((c=getchar( ))!='\n')
{if ((c>='a'&&c<='z')||(c>='A'&&c<='Z'))
{c=c+4;
if(c>'Z'&&c<='Z'+4||c>'z')c=c-26;
}
cout<'Z'||c>'z') c=c-26;因为所有小写字母都满足"c>'Z'"条件,从而也执行"c=c-26;"语句,着就会出错.因此必须限制其范围为"c>'Z'&&c<='Z'+4",即原字母为'W'到'Z',在此范围以外的不是原大写字母W~Z,不应按此规律转换.请考虑:为什么对小写字母不按此处理,即写成c>'z'&&c<='z'+4而只须写成"c>'z'"即可.
2006年1月30日
#
常变量是从应用需要的角度提出的,例如有时要求某些变量的值不允许改变(如函数的参数),这时就用const加以限定.
请区别用#define命令定义符号常量和用const定义的常变量.符号常量只是用一个符号代替一个字符串,在编译时把所有符号常量替换为指定的字符串,它没有类型,在内存中并不存在以符号常量命名的存储单元.而常变量具有变量的特征,它具有类型,在内存中存在着以它命名的存储单元,可以用sizeof运算符测出其长度.与一般变量唯一不同的是指定变量的值不能改变.用#define命令定义符号常量是C语言所采用的方法,C++把它保留下来是为了和C兼容.C++的程序员一般喜欢用const定义常变量.虽然二者实现的方法不同,但从使用的角度看,都可以认为用一个标识符代表了一个常量.有些书上把用const定义的常变量也称为定义常量,但我们应该了解它和符号常量的区别.
2006年1月23日
#
C++是从C语言发展而来的,为了与C兼容,C++保留了C语言中的一些规定.其中之一是头文件的形式,在C语言中头文件用.h作为后缀,如stdio.h,math.h,string.h等.在C++发展初期,为了和语言兼容,许多C++编译系统保留头文件以.h为后缀的用法,如iostream.h.但后来ANSI C++建议头文件不带后缀.h.近年推出的C++编译系统新版本则采用了C++的新方法,提供了一批不带后缀的头文件,如用iostream,string,cmath等作为头文件名.但为了使原来编写的C++程序能够运行,仍允许使用原有的带后缀.h的头文件,即二者同时并存,由用户选用.
上篇最简单的C++程序也可以写成下面的形式:
#include //
void main( )
{cout<<"This is a C++ program.";
}
由于C语言无命名空间,因此用带后缀.h的头文件时不必用"using namespace std;"作声明.
此外,C语言不要求main函数返回整数,main函数不必指定为int型,一般用void型(无返回值),这样,main函数中最后一个语句"return 0;"也无必要了.
不过,一些新版本的C++编译系统中则无法通过编译,新版本的C++编译系统严格执行C++标准.为了更好的维护系统和适应新的发展,应该能看懂老的程序,并能将它们改写为标准C++的形式.提倡在编写新的程序时按照标准C++的规定进行.这就答到了写本篇的目的.
最简单的C++程序
#include //包含头文件 instream
using namespace std; //使用命名空间 std
int main( )
{
cout<<"This is a C++ program.";
return 0;
}
运行时会在屏幕上输出以下信息:
This is a C++ program.
该程序囊括了作为C++程序的必备要素 实现了最简单的输出功能 可谓麻雀虽小 五脏俱全哈 初学者可用此程序来检验一般程序的完整性
复杂些的C++程序
#include //预处理命令
using namespace std; //使用命名空间 std
int main( ) //主函数首部
{ //函数体开始
int a,b,sum; //定义变量
cin>>a>>b; //输入语句
sum=a+b; //赋值语句
cout<<"a+b="< //预处理命令
using namespace std;
int max(int x,int y) //定义max函数,函数值为整型,形式参数x,y为整型
{ //max函数体开始
int z; //变量生命,定义本函数中用到的变量z为整型
if(x>y) z=x; //if语句,如果x>y,则将x的值赋给z
else z=y; //否则,将y的值赋给z
return(z); //将z的值返回,通过max带回调用处
} //max函数结束
int main( ) //主函数
{ //主函数体开始
int a,b,m; //变量声明
cin>>a>>b; //输入变量a和b的值
m=max(a,b); //调用max函数,将得到的值赋给m
cout<<"max="< //预处理命令
using namespace std;
class Student //声明一个类,类名为Student
{private: //以下为类中的私有部分
int num; //私有变量num
int score; //私有变量score
public: //以下为类中的公用部分
void setdata( ) //定义公用函数setdata
{cin>>num; //输入num的值
cin>>score; //输入score的值
}
void display( ) //定义公用函数display
{cout<<"num="<
2006年1月22日
#
1954年 FORTRAN语言 用于科学计算是世界上第一种计算机高级语言
1964年 BASIC语言 FORTRAN语言的基础上简化而成 为初学者设计的小型高级语言 被称为"大众语言"
1972年 C语言 由美国贝尔实验室的D.M.Ritchie研制成功 结构化和模块化的面向过程语言 为计算机专业人员设计
20世纪80年代初 C++语言 由AT&TBell实验室的Bjarne Stroustrup博士及其同事开发成功 既可用于面向过程的结构化又可用于面 向对象的程序设计 为了解决软件危机 与C兼容
AT&T发布的第一个C++编译系统实际上是一个预编译器(前端编译器) 把C++代码转化成C代码
1988年 第一个真正的C++编译系统诞生
1989年 C++2.0版本出现 包括了类的多继承
1991年 C++3.0版本出现 增加了模板
C++4.0版本则增加了异常处理 命名空间 运行时类型识别(RTTI)等功能
1997年 以4.0版本为基础制订的ANSI C++标准正式通过并发布
2006年1月19日
#
C++是从C语言发展而来的,为了与C兼容,C++保留了C的许多用法,人们在编写C++程序时也常常沿用C的某些传统用法。例如,主函数为viod类型,无返回值;头文件带后缀.h;使用系统库时不使用命名空间等。但是,ANSI C++标准有新的规定,要求主函数为int类型,如果程序正常执行则返回0值;系统头文件不带后缀.h;使用系统库时使用命名空间std;增加了字符串类型string等。
虽然C++仍然允许使用从C继承来的传统用法,但建议大家从一开始就按照C++标准编写程序,养成C++的编程风格。本博客程序形式如下:
#include //头文件不带后缀.h
#include //包含string头文件
using namespace std; //使用系统库时使用命名空间std
int main() //主函数为int类型
{ ```
string str; //定义字符串变量str
```
return0; //程序正常执行则返回0
}
依据C++标准介绍的.
2006年1月18日
#
GCC最早是GNU-C-Compiler(GNU C 语言编译器)的缩写,现在则是GNU-Composed-Compiler(GNU编译器集群)的缩写。GNU的著名代表项目是Linux。GNU是一个没有实际意义的“自缩略语”——Gnu is Not UNIX。意思是“Gnu 不是UNIX"。在1983年一些早年的UNIX开发者发起了一个开放软件运动。他们认为,软件应当是开放的,任何人都应该可以接触到源代码,这样不仅用户可以随时根据自己的需要修改程序,而且软件本身也可以通过类似生物进化的模式(无限分支,优胜劣汰)得到全面的完善。由于当时UNIX主要由软件厂商所控制,因此GNU决定给自己起名叫"Not UNIX",表示有别于UNIX。
GCC是一个开放的程序语言编译器。GCC的核心是C/C++编译器。GCC与众不同的特点在于它是完全开放的,是自由软件,可以从网上下载,任何人都可以免费得到这个软件包甚至源代码。由于GCC的开放性,它已经被软件行业的自由开发者移植到各种不同平台。它既可以用于Windows环境,也可以用于DOS,UNIX,Linux等操作系统。
由于GCC不属于赢利性的公司,没有任何商业意图,因而其实现的功能最接近ANSI标准,GCC是目前最标准的C/C++语言编译器之一。使用GCC的程序人员的习惯可以说是最好的。因为他们习惯于正确使用标准的C/C++用法。由于没有商业目的,GCC不会出现“为了收钱而升级”的情况,因此其产品本身比较稳定,不需要进行不必要的更新。由于有不同的开发人员将GCC移植到了多种不同平台,为GCC写的程序,在各个平台之间,是源代码级兼容的(个别直接操作硬件的程序除外)。这为移植程序打下了良好基础。GCC在国外应用十分广泛,很有发展前途。建议读者熟悉它、使用它。
DJGPP是GCC在DOS/Windows平台上的实现。
作为开放软件,GCC并不是“一个”软件。使用DJGPP需要了解与DJGPP集成在一起的另一个重要软件RHIDE。RHIDE不是一个编译器,而是一个开发环境(编译调试环境)。它提供了一个界面供开发者输入和编辑、调试与运行。而真正的编译工作是由DJGPP(gcc.exe)完成的(RHIDE在后台调用gcc.exe来编译,并将编译信息显示在RHIDE的窗口里)。