C++语言基本(1)
副标题#e#
入门简介
变量 C++数据范例 C++操纵符 C++中的函数 main函数 数组 字符串数组 字符串操纵函数
C++是个强大的语言,可以用于做此外语言做不了的事情。可是,这种强大成果是有价钱的。开始利用C++时,你大概会碰着内存溢出和会见失效等问题,使措施死机。这里用最简短的篇幅先容C++语言基本。C++语言自己有专著先容,这种书还出格厚,所以别指望我能用三言两语说清楚。读者学完本书并利用C++ Builder一般时间之后,最后对C++语言再作更深入的相识。
C++可以最充实地操作面向工具编程(OOP)的优势。OOP不可是一个新名词,而有它的实际意义,可以生成可复用的工具。新术语 工具(object),和前面先容的构件一样,是完成特定编程任务的软件块(构件是工具,但工具不全是构件,稍后会表明这点)。工具只向用户(利用工具的编程人员)显示必需的部门,从而简化工具的利用。用户不必知道的所有内部机制都埋没在幕后。这一切都包罗在面向工具编程的观念中。OOP可以用模块化要领举办编程,从而制止每次从新开始。C++ Builder措施是面向OOP的,因为C++ Builder大量利用构件。生成构件后(你生成的或C++ Builder内置的构件),就可以在任何C++ Builder措施中反复利用。构件还可以扩展,通过担任生成具有新成果的新构件。最妙的是,构件埋没了所有内容细节,使编程人员能会合精神充实操作构件。
入门简介
在C++之前先有C语言,C++是成立在C语言之上的,称为“带类的C语言”。这个C语言基本在当今的C++措施中仍然很重要。C++并不是代替C,而是增补和支持C。本章余下部门和下几章主要先容C++中来历于C语言的部门。实际上,这里先容的是C语言,第2课"C++基本"中才转入C++。读者不必体贴哪个来自C,哪个来自C++,因为这些全在C++中。C++语言很难按顺序先容,因为我们要先容的所有特性都是交错的。我筹备的一次先容一块,然后拼凑起来。到第3课"高级C++"竣事,你将对C++语言有个完整的相识。一下子没有把握某个观念也不要紧,有些观念必需颠末实践才气完全相识。
变量
照旧从变量讲起来吧。变量(variable)实际上是赋予内存地点的名称。声明变量后,就可以用它操纵内存中的数据。下面举几个例子举办说明。下列码段用了两个变量,每条语句末端用说明语句描写执行该语句时产生的环境:
int x;// variable declared as an integer variable
x = 100;// ‘x’ now contains the value 100
x +=50;// ‘x’ now contains the value 150
int y = 150;// ‘y’ declared and initialized to 150
x += y;// ‘x’ now contains the value 300
x++;// ‘x’ now contains the value 301
新术语 变量(variable)是留作存放某个数值的计较机内存地点。留意x的值在变量操纵时会改变,稍后会先容操纵变量的C++操纵符。告诫 声明而未初始化的变量包括随机值。由于变量所指向的内存还没有初始化,所以不知道该内存地点包括什么值。
譬喻,下列代码
int k;
int y;
x=y+10; //oops!
本例中变量y没有事先初始化,所以x大概取得任何值。破例的环境是全局变量和用static修饰声明的变量老是初始化为0。而所有其它变量在初始化或赋值之前包括随机值。变量名可以殽杂大写、小写字母和数字与下划线(_),但不能包括空格和其它非凡字符。变量名必需以字母或下划线开始。一般来说,变量名以下划线或双下划线开始欠好。变量名答允的最大长度随编译器的差异而差异。假如变量名保持在32个字符以下,则绝对安详。实际中,任何高出20个字符的变量名都是不实用的。
下例是有效变量名的例子:
int aVeryLongVariableName;// a long variable name
int my_variable;// a variable with an underscore
int_ x;// OK,but not advisedint X;// uppercase variable name
int Labe12;// a variable name containing a number
int GetItemsInContainer(); // thanks Pete!
说明 C++中的变量名是思量巨细写的,下列变量是差异的:int XPos;int xpos;假如你原先所用语言不思量巨细写(如Pascal),则开始打仗思量巨细写的语言大概不太适应。
#p#副标题#e#
C++数据范例
新术语 C++数据范例界说编译器在内存中存放信息的方法。在有些编程语言中,可以向变量赋予任何数值范例。譬喻,下面是BASIC代码的例子:x = 1;x = 1000;x = 3.14;x = 457000;在BASIC中,翻译器能思量按照数字长度和范例分派空间。而在C++,则必需先声明变量范例再利用变量:int x1 = 1;int x = 1000;float y = 3.14;long z = 457000;这样,编译器就可以举办范例查抄,确保措施运行时一切顺利。数据范例利用不妥会导致编译错误或告诫,以便阐明和更正之后再运行。有些数据范例有带标记和无标记两种。带标记(signed)数据范例可以包括正数和负数,而无标记(unsigned)数据范例只能包括正数。表1.1列出了C++中的数据范例、所要内存量和大概的取值范畴。
表1.1C++数据范例(32位措施)
数据范例 字节 数取值范畴
char 1 -128到126
unsigned char 1 0到255
short 2 -32,768到32,767
unsigned short 2 0到65,535
long 4 -2,147,483,648到2,147,483,648
unsigned long 4 0到4,294,967,295
int 4 同long
unsigned int 4 同unsigned long
float 4 1.2E-38到3.4E381
double 8 2.2E-308到1.8E3082
bool 1 true或false
#p#分页标题#e#
从上表可以看出,int与long沟通。那么,为什么C++还要区分这两种数据范例呢?实际上这是个遗留问题。在16位编程情况中,int要求2个字节而long要求4个字节。而在32位编程情况中,这两种数据都用4个字节存放。C++Builder只生成32位措施,所以int与long沟通。说明 在C++ Builder和BorLand C++ 5.0中,Bool是个真正的数据范例。有些C++编译器有Bool要害字,则Bool不是个真正的数据范例。有时Bool只是个typedef,使Bool等价于int。typedef实际上成立别名,使编译器在一个标记与另一标记间划上等号。typedef的语法如下:typedef int Bool;这就汇报编译器:Bool是int的别名。说明 只有double和float数据范例利用浮点数(带小数点的数)。其它数据范例只涉及整数值。尽量integer数据范例也可以指定带小数点的数值,但小数部门会舍弃,只将整数部门赋予整型变量,譬喻:int x=3.75;获得的x取值为3。留意,这个整数值并不是四舍五入,而是放弃小数部门。顺便说一句,大大都Windows措施很罕用到浮点数。C++可以在须要时举办差异数据范例间的换算。譬喻:short result;long num1 = 200;long num2 = 200;result = num1 * num2;这里我想将两个长整型的积赋予一个短整型。尽量这个公式混用了两种数据范例,但C++可以或许举办换算。计较功效会奈何呢?功效会让你大吃一惊,是25536,这是绕接(wrop)的功效。从表1.1可以看出,短整型的最大取值为32767,在最大值之上加1会怎么样呢?获得的是32768。这实际上与汽车里程计从99999回到00000的原理一样。为了说明这点,请输入并运行下列清单1.3中包括的措施。
清单1.3Wrapme.cpp
1: #include <iostream.h>
2: #include <conio.h>
3: #pragma hdrstop
4:
5: int main(int argc,char **argv)
6: {
7:short x = 32767;
8:cout << " x = " << x << endl;
9:x++;
10: cout << " x = " << x << endl;
11: getch();
12: return 0;
13: }
说明后头几节要先容的有些清单没有下列语句:
#include<condefs.h>
C++ Builder生成新的节制台应用措施时会自动加上这条语句。这在你所用的措施中不是必需的,所以代码清单中将其省略。无论有无这条语句,措施运行功效是一致的。阐明输出功效为:x=32767 x=32768假如用int数据范例,则不会有这个问题,因为int数据范例的取值范畴在正向20亿之间,一般不会有绕回的问题。但这时措施大概会稍大一些,因为int需要4字节存储,而short只需要2字节存储。对付大大都应用措施,这个不同是不显著的。前面先容了自动范例换算。有时C++无法举办换算,这时大概在编译器中发生编译错误,说Cannot convert from x to y(无法从x换算到Y)。编译器也大概告诫说Conversion might lose significant digits(换算大概丢失显著位)。提示 编译器告诫应看成编译器错误,因为它表白出了错误。我们应尽力生成无告诫的编译。有时告诫无法制止,但必然要当真查抄所有告诫。应充实相识告诫的原因并只管予以更正。
C++操纵符
操纵符(operator)用于操纵数据。操纵符举办计较、查抄等式、举办赋值、操纵变量和举办其它更奇怪的事情。C++中有很多操纵符,这里不想列出全部,只列出最常用的操纵符,如下表所示。表1.2常用C++操纵符操纵符说明举例
算术运算符
+ 加 x=y+z;
– 减 x=y-z;
* 乘 x=y*z;
/ 除 x=y/z;
赋值运算符
= 赋值 x=10;
+= 赋值与和 x+=10;(便是x=x+10;)
-= 赋值与减 x-=10;
*= 赋值与乘 x*=10;
\= 赋值与除 x\=10;
&= 赋值位与 x&=0x02;
|= 赋值位或 x|=0x02;
逻辑操纵符
&& 逻辑与 if(x && 0xFF) {…}
|| 逻辑或 if(x || 0xFF) {…}
等式操纵符
== 便是 if(x == 10) {…}
!= 不便是 if(x != 10) {…}
< 小于 if(x < 10) {…}
> 大于 if(x > 10) {…}
<= 小于或便是 if(x <= 10) {…}
>= 大于或便是 if(x >= 10) {…}
一元操纵符
* 间接操纵符 int x=*y;
& 地点操纵符 int* x=&y;
~ 位非 x &=~0x02;
! 逻辑非 if(!valid) {…}
++ 递增操纵符 x++(便是x=x+1;)
— 递减操纵符 x–;
类和布局操纵符
:: 范畴理会 MyClass :: SomeFunction();
-> 间接成员 MyClass-> SomeFunction();
· 直接成员 MyClass . SomeFunction();
#p#分页标题#e#
可以看出,这个清单长了些,没法一下子记着。利用C++时,你会逐步熟悉这些操纵符的。必需指出,递增操纵符既可用作前递增(++x),也可用作后递增(x++)。前递增操纵符汇报编译器先递增再利用变量,尔后递增操纵符则让编译器先利用变量值再递增。譬喻下列代码:
int x = 10;
cout << "x = " << x++ << end1;
cout << "x = " << x << end1;
cout << "x = " x << end1;
cout << "x = " << ++x << end1;
输出功效如下:
x=10
x=11
x=12
x=12
递减操纵符也是这样,这里不想将这些内容讲得太深,但读者可以耐性阅读下去,正如彭兹对奥古斯特所说,“奥古,耐性点,罗马不是一天建成的”。说明 在C++中操纵符可以过载(overload)。编程人员可以通过过载尺度操纵符让它在特定类中举办特定运行。譬喻,可以在一个类中过载递增操纵符,让它将变量递增10而不是递增1。操纵符过载是个高级C++技能,本书禁绝备具体先容。你也许会发明,有些操纵符利用了沟通的标记。标记的意义随情境的差异而差异。譬喻,星号(*)可以作为乘号、声明指针或打消指针引用。这初看起来有点乱,事实上,C++编程内行有时也以为有点乱。多实践,你会逐步适应的。本书有很多例子先容这些操纵符。读者不必死记每个操纵符的浸染,而可以在进修中通过措施和码段去领略其浸染。
C++中的函数
函数是与主措施分隔的码段。这些码段在措施中需要举办特定行动时挪用(执行)。譬喻,函数大概取两个值并对其举办巨大的数学运算。然后返回功效,函数大概取一个字串举办阐明,然后返回阐明字串的一部门。新术语 函数(function)是与主措施分隔的码段,举办预定的一个处事。函数是各类编程语言的重要部门,C++也不破例。最简朴的函数不带参数,返回void(暗示不返回任何对象),其它函数大概带一个或几个参数并大概返回一个值。函数名法则与变量名沟通。图1.5显示了函数的组成部门。新术语 参数(parameter)是通报给函数的值,用于改变操纵或指示操纵水平。
返回范例 函数名 参数表
↓ ↓ ↓
int SomeFunction(int x, int y){
函数体→int z = (x * y); return z; ↑返回语句
}
图1.5函数的组成部门利用函数前,要先举办声明。函数声明或原型(prototype)汇报编译器函数所取的参数个数、每个参数的数据范例和函数返回值的数据范例。清单1.4列示了这个观念。新术语 原型(prototype)是函数外观的声明或其界说的说明。
清单1.4Muttiply.cpp
1: #include <iostream.h>
2: #include <conio.h>
3: #pragma hdrstop
4:
5: int multiply(int,int)
6: void showResult(int);
7:
8:int main(int argc,char **argv);
9:{
10: int x,y,result;
11: cout << end1 << "Enter the first value:";
12: cin >> x;
13: cout << "Enter the second value: ";
14: cin >> y;
15: result=multiply(x,y);
16: showResult(result);
17: cout << end1 << end1 << "Press any key to continue…";
18: getch();
19: return 0
20: }
21:
22: int multiply(int x,int y)
23: {
24:return x * y;
25: }
26:
27: void showResult(int res)
28: {
29:cout << "The result is: " << res <<end1;
30: }
这个措施的11到14行用尺度输入流cin向用户取两个数字,第15行挪用multiply()函数将两个数相乘,第16行挪用showResult()函数显示相乘的功效。留意主措施前面第5和第6行multiply()和showResult()函数的原型声明。原型中只列出了返回范例、函数名和函数参数的数据范例。这是函数声明的最根基要求。函数原型中还可以包括用于建档函数成果的变量名。譬喻,multiply()函数的函数声明可以写成如下:int multiply(int firstNumber,int secondNumber);这里函数multiply()的浸染很明明,但代码既可通过说明也可通过代码自己建档。留意清单1.4中函数multiply()的界说(22到25行)在主函数界说码段(8到20行)之外。函数界说中包括实际的函数体。这里的函数体是最根基的,因为函数只是将函数的两个参数相乘并返回功效。清单1.4中函数multiply()可以用多种要领挪用,可以通报变量、直接数或其它函数挪用的功效:
result = multiply(2,5);//passing literal values
result = multiply(x,y); //passing variables
showResult(multiply(x,y));
//return value used as a
//parameter for another function
multiply(x,y);//return value ignored
#p#分页标题#e#
留意 最后一例中没有利用返回值。本例中挪用函数multiply()而不消返回值没什么原理,但C++编程中常常忽略返回值。有很多函数是先举办特定行动再返回一个数值,暗示函数挪用的状态。有时返回值与措施无关,可以忽略不计。假如将返回值忽略,则只是放弃这个值,而不会有此外危害。譬喻,前面的样本措施中忽略了getch()函数的返回值(返回所按键的ASCII值)。函数可以挪用其它函数,甚至可以挪用本身,这种挪用称为递归(recursion)。这在C++编程中是个较巨大的问题,这里先不先容。新术语 递归(recursion)就是函数挪用本身的进程。本节先容的函数指的是C或C++措施中的独立函数(独立函数不是类的成员)。C++中的独立函数可以和C语言中一样利用,但C++将函数进一步深化,将在稍后先容C++时先容。
函数法则
· 函数可以取任意多个参数或不取参数。
· 函数可以返回一个值,但函数不强求返回一个值。
· 假如函数返回void范例,则不能返回数值。
假如要让返回void范例的函数返回数值,则会产生编译错误。返回void范例的函数不需包括return语句,但也可以包括这个语句。假如没有return语句,则函数达到末端的竣事大括号时自动返回。
· 假如函数原型暗示函数返回数值,则函数体中应包括返回数值的return语句,假如函数不返回数值,则会产生编译错误。
· 函数可以取任意多个参数,但只能返回一个数值。
· 变量可以按数值、指针或引用通报给函数(将在稍后先容)。
语法:函数语句的声明(原型)名目如下: ret_type function_name(argtype_1 arg_1,argtype_2 arg_2,…,argtype_n arg_n);
函数声明暗示代码中要包罗的函数,该当显示函数的返回数据范例(ret_type)和函数名(function_name),暗示函数所要数据变元的顺序(arg_1,arg_2,…,arg_n)和范例(argtype_1,argtype_2,…argtype_n)。
函数语句的界说名目如下:
ret_type function_name(argtype_1 arg_1,argtype_2 arg_2,…,argtype_narg_n);
{ statements;
return ret_type; }
函数界说暗示组成函数的代码块(statements),该当显示函数的返回数据范例(ret type)和函数名(function_name),包罗函数所要数据变元(arg_1,arg_2,…,arg_n)和范例(argtype_1,argtype_2,…argtype_n)。
main()函数
C++措施必需有main()函数。main()函数是措施的进口点。前面先容的每个样本措施都有main()函数。可是,并非所有C++措施都有传统的main()函数。用C或C++写成的Windows措施进口点函数称为WinMain(),而不是传统的main()函数。说明 C++ Builder GUI应用措施有WinMain(),但埋没起来了。C++ Builder利用户无需思量Windows措施的初级细节,而可以会合思量措施用户界面和其它部门的建设。main()函数和其它函数一样是函数,有沟通的组成部门。在32位节制台应用措施中,C++ Builder生成具有下列原型的缺省main()函数:int main(int argc,char** argv);这个main()函数形式取两个参数并返回一个整型值。前面说过,数值在挪用函数时通报给函数。但对付main()函数,没有直接挪用,而是在措施运行时自动执行。那么,main()函数如何取得参数呢?步伐是从呼吁行取得。现说明如下:假设有个Win32节制台应用措施要在DOS提示下用下列呼吁行执行:grep WM_KILLFOCUS 杁 -i
这里要用呼吁行变元WM_KILLFOCUS、d和i启动措施grep,我们要演示如安在main()函数中将其变为argc和argv.首先,整型变量argc包括呼吁行中通报的参数个数,至少为1,因为措施名也算作参数。变量argv是个数组,包括字串的指针。这个数组包括呼吁行中通报的每个字串。本例中:
argc包括4
argv[0] 包括C:|cbuilder|bin|grep.exe
argv[1] 包括WM_KILLFOCUS
argv[2] 包括 d
argv[3] 包括 i
下面用一个小措施验证这个事实。在C++ Builder中生成新的节制台应用措施并输入清单1.5所示的措施。清单1.5Argstest.cpp
1: #include <iostream.h>
2: #include <conio.h>
3: #pragma hdrstop
4:
5: int main(int argc,char **argv)
6: {
7:cout << "argv = "argc << end1;
8.for (int i=0;i<argc;i++)
9. cout << "Parameter " << i << ": " << argv[i]<< end1;
10. cout << end1 << "Press any key to continue…";
11: getch();
12: return 0;
13: }
#p#分页标题#e#
将这个项目存为Argstest,然后不是单击Run按钮,而是选择主菜单中的Project|Build All,这样只成立项目而不执行措施。项目建成后,选择主菜单中的Run|Parameters,在RunParameters对话框RunParameters字段中输入下列内容:one two three "four five" six然后单击Run按钮,措施即用所指定的呼吁行参数运行。另一种步伐是用下列呼吁行在DOS提示下运行措施:argstest one two three "four five" six措施运行时,它会显示传入的变元数,然后列出每个变元。运行屡次,每次提供差异呼吁行变元,留意发生的功效。
大大都措施中main()函数的返回值并不重要,因为凡是不利用返回值。事实上,可以不要求main()函数返回数值。main()函数的形式有多种,下列声明均有效:main();int main();// same as above
int main(void); // same as above
int main(int argc,char** argv);
void main();
void main(int argc, char** argv);
尚有更多的形式。假如不想利用呼吁行变元,则可以用第一种main()函数形式,其不取参数(括号内为空的)并返回一个int(不指按时返回缺省返回值)。换句话说main()函数最根基的形式不取参数并返回一个int。
数组
任何C++固有数据范例都可以放进数组中。数组(array)就是数值的荟萃。譬喻,假设要生存一个整型数组,放五个整型值。可以声明数组如下:int myArray[5];这里编译器为数组分派图1.7所示的内存空间。由于每个int要4个字节存储,所以整个数组占用20字节的内存空间。
mArray[0]mArray[1]mArray[2]mArray[3]
mArray[4]
baseAddrbasseAddr+4baseAddr+8
baseAddr+12baseAddr+16
声明数组后,就可以用如下脚标操纵符([])填入数值:
myArray[0] = -200;
myArray[1] = -100;
myArray[2] = 0;
myArray[3] = 100;
myArray[4] = 200;
由上可见,C++中的数组是以0为基数的。后头措施中可以用脚标操纵符会见数组的各个元素:
int result=myarray[3]+myArray[4]; // result will be 300
尚有一次声明和填入整个数组内容的简便要领如下:
int myArray[5] = {-200, -100,0,100,200};
进一步说,假如知道数组的元素个数,并在声明数组时填凑数组,则声明数组时连数组长度都可以省略。譬喻:int myArray[] = {-200, -100,0,100,200 };这是可行的,因为编译器从赋予的数值表可以判定出数组中元素的个数和分派给数组的内存空间。
数组可以是多维的。为了生成两维整型数组,可用下列代码:
int mdArray[3][5];
这样就分派15个int空间(共60字节)。数组的元素可以和一维数组一样会见,只是要提供两个脚标操纵符:int x = mdArray[1][1]+mdArray[2][1];
图1.8两维数组在内存中的样子告诫 留意不要重载数组末端。
C++一个强大的特性是能直接会见内存。由于这个特性,C++无法阻止你写入特定内存地点,纵然这个地点是措施不让会见的。下列代码是正当的,但会导致措施或Windows瓦解:int array[5];array[5]=10;这是常见的错误,因为数组是以0为基数的,最大脚标应是4而不是5。假如重载数组末端,则无法知道哪个内存被改写了,使功效难以预料,甚至会导致措施或Windows瓦解。这类问题很难诊断,因为受影响的内存凡是要在好久今后才会见,这时才产生瓦解(让你莫名个中之妙)。所以写入数组时必然要小心。
数组法则
·数组是以0为基数。数组中的第一个元素为0,第二个元素为1,第三个元素为2,等等。
·数组长度应为编译常量。编译器在编译时必需知道为数组分派几多内存空间。不能用变量指定命组长度。所以下列代码不正当,会导致编译错误:
int x = 10;int myArray[x]; // compiler error here·
小心不要重载数组末端。
· 大数组从堆叠(heap)而不是仓库(stack)中分派(详见稍后)。· 从堆叠分派的数组可以用变量指定命组长度。譬喻:int x = 10;int* myArray = new int[x]; // this is OK
字符数组
奇怪的是,C++不支持字串变量(安排文本的变量),C++措施中的字串是用char数据范例的数组暗示的。譬喻,可以将变量赋予char数组如下:
char text[] = "This is a string.";
这就在内存中分派18字节的内存空间用于存放字串。按照你的贯通本领,也许你会发明该字串中只有17个字符。分派18个字节的原因是字串要以终止null末了,C++在分派内存空间时把终止null算作一个字符。
#p#分页标题#e#
新术语 终止null是个非凡字符,用|0暗示,便是数值0。措施碰着字符数组中的0时,暗示已经到字串末端。为了说明这点,输入并运行下列节制台应用措施。
清单1.6Nulltest.cpp
1: #include <iostream.h>
2: #include <conio.h>
3: #pragma hdrstop
4:
5: int main(int argc,char **argv)
6: {
7:char str[]="This is a string.";
8.cout << str << end1;
9.str[7]= ‘\0’;
10. cout << str << end1
11. cout << end1 << "Press any key to continue…";
12: getch();
13: return 0;
14: }
阐明 最初,字符数组包括字符串This is a string和一个终止null,这个字勾串过cout送到屏幕上。下一行将数组的第7个元素赋值为|0,即终止null。字串再次发送到屏幕上,但这时只显示This is。原因是计较机认为数组中字串在第7个元素上终止,余下字串仍然在内存空间中,但不显示,因为碰着了终止null。图1.10演示了将数组的第7个元素赋值为|0的语句前后的字符数组。
之前
Thi
sisastri
ng.\0
之后
This
is\0astri
ng.\0
图1.10字符数组的内容
清单1.6中也可以赋值0而不是’|0’,功效沟通,因为数字0和char数据范例’|0’是等值的。譬喻,下列语句是等价的:
str[7] = ‘|0’;
str[7] = 0;
说明 C++措施中单引号与双引号是有不同的。向数组元素赋值终止null和其它字符值时,必需用单引号。单引号的浸染是将引号内的字符酿成整型值(该字符的ASCII值),然后将这个值存放在内存地点中。将字串赋予字符数组时,必需用双引号。假如用错引号,则编译器会产生编译错误。
字串操纵函数
假如你用过具有string数据范例的编程语言,你大概很不习惯,别人也有同感,所以尺度C语言库中提供了几个字串操纵函数。表1.3列出了最常用的字串操纵函数及其用法说明。关于每个函数的具体说明和实例,见C++ Builder联机辅佐。
表1.3字串操纵函数
函数 说明
strcat() 将字串接合到方针字串的末端
strcmp() 较量两个字串是否相等
strcmpi() 较量两个字串是否相等,不思量巨细写
strcpy() 将字串内容复制到方针字串中
strstr() 扫描字串中第一个呈现的字串
strlen() 返回字串长度
strupr() 将字串中的所有字符酿成大写
sprintf() 按照几个参数成立字串
说明 这里先容的字串操纵是C语言中的字串处理惩罚要领。大大都C++编译器提供了cstring类,可以简化字串的处理惩罚(C++ Builder的Visual构件库中有个AnsiString类,可以处理惩罚字串操纵。C++ Builder联机辅佐中具体先容了AnsiString类)。尽量C语言中的字串处理惩罚要领较量贫苦,但并不外时,C++编程人员常常在利用cstring类和AnsiString类等字串类的同时利用C语言中的字串处理惩罚要领。这里不想对表中的每个函数举办举例说明,只想举两个最常用的函数。strcpy()函数将一个字串复制到另一字串中,源字串可以是变量或直接字串。譬喻下列代码:
//set up a string to hold 29 characters
char buff[30];
//copy a string literal to the buffer
strcpy (buff,"This is a test.");//display it
cout << buff << end;
//initialize a second string buffer
char buff2[]="A second string.";
//copy the contents of this string to the first buffer
strcpy (buff,buff2);
cout << buff << end1;
字符数组中比数字数组中更容易重载数字末端。譬喻下列代码:
char buff[10]= "A string";// later….
strcpy(buff,"This is a test."); //oops!
这里成立了放10个字符的字符数组,最初指定需要9个字节的字符串(记着终止null)。厥后大概健忘了数组长度,将需要16个字节的字串复制到了缓冲区,对数组重载了六个字节。这个小小错误就擦去了某个内存位置上的六个字节。所以将数据复制到字符数组中时要出格小心。另一个常用的字串函数是sprintf()。这个函数可以殽杂文本和数字成立名目化字串。下面例子将两个数相加,然后用sprintf()成立字串以陈诉功效:
char buff[20];
int x = 10 * 20;
sprintf(buff,"The result is: %d",x);
cout << buff;
执行这个码段时,措施显示下列功效:The result is:200
本例中%d汇报sprintf()函数此处有个整型值,名目字串末端插入变量x,汇报sprintf()在字串的这个位置放上变量x的值。sprintf()是个出格的函数,可以取多个变元。你必需提供方针缓冲区和名目字串,但名目字串后头的变元数是个变量。下面的sprintf()例子用了别的三个变元:
int x = 20;
int y = 5;
sprintf(buff, "%d + %d", x, y, x + y);
cout << buff;
执行这个码段时,屏幕上显示的功效如下:20 + 5 = 25
说明 C++字串中的单斜杠暗示非凡字符。譬喻,’\n’暗示新行符,’\t’暗示跳表符。为了在字串中放上实际的斜杠,要用双斜杠如下:
strcpy(fileName, "c:\\windows\\system\\win.ini");
#p#分页标题#e#
很多编程人员因为忘了这个简朴的事实而夜不能寐,苦苦折腾。这是个常见的错误,别说我没有汇报你。sprintf()有个兄弟叫wsprintf(),是Windows版的sprintf().Windows措施中大概同时用这两个函数。wsprintf()与sprintf()的浸染相似,独一的不同是不能在名目字串中放上浮点数。C++ Builder措施中两个函数均可利用,但用sprintf()更好,因为它完全支持浮点数(还可以少输入一个字符)。关于sprintf()的进一步先容,见C++ Builder联机辅佐。
字串数组不只可以有字符数组,还可以有字符数组的数组(即字串数组)。这听起来有点巨大,其实前面的Argstest措施中已经用过。这类数组可以分派如下:
char strings[][20] = {
"This is string 1",
"This is string 2",
"This is string 3",
"This is string 4"};
这个代码生成四个字串的数组,每个字串最多放19个字符。尽量可以利用这种字串数组,但C++ Builder中尚有更简朴的字串数组处理惩罚步伐(将在后头先容C++ Builder时先容)。说明 假如常常用到字串数组,该当看看尺度模板库(STL).STL提供了比用C语言式字符数组更利便地存放和操纵字串数组的要领.STL中尚有个string类。