目录
一、C++ 语言的发展简史
二、C++ 语言的特点
(1)基本的输入/输出
(2)头文件和命名空间
(3)强制类型转换运算符
(4)函数参数的默认值
(5)引用和函数参数的传递
① 引用的定义
② 引用在函数中的使用
(6)const 与指针共同使用
(7)内联函数
(8)函数的重载
(9)指针和动态内存分配
(10)用 string 对象处理字符串
① string 对象的使用
② string 对象的声明
③ string 对象的操作
三、C++ 语言的程序结构
一、C++ 语言的发展简史
⚫ 将程序设计语言分为低级语言、中级语言和高级语言。
- 机器语言和汇编语言属于低级语言一类,因为它们能够直接操纵计算机的寄存器和内存。
- 机器语言是一种依赖于 CPU 的指令系统,使用机器指令的二进制代码编写程序,能够直接被计算机识别。
- 汇编语言使用能够代表指令的助记符来编写程序,可以看作是符号化了的机器语言。
⚫ 高级语言是面向用户的语言。
- 很多语言在形式上接近于算术语言和自然语言,程序员编写方便。
- 使用高级语言编写的程序易读且通用性强,但大部分不能直接与硬件打交道,也不能直接在计算机上运行,需要系统软件的支持,如需要编译程序及链接程序将高级语言编译链接为机器指令后才能运行。
⚫ C 语言是 C++ 语言的前身,在进一步扩充和完善 C 语言的基础上得到了 C++ 语言。
二、C++ 语言的特点
- 它是 C 语言的继承,尽量兼容 C 语言,既保持了 C 语言的简洁和高效,可以像 C 语言那样进行结构化程序设计,同时也增强了 C 语言对类型的处理。
- 加入了面向对象的特征,可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。
与 C 语言相比,C++ 语言的优点:
- 从程序运行的稳定性来说,C++ 语言比 C 语言更安全,它支持过程化编程、面向对象编程和泛型编程。因为能够支持面向对象的开发方式,所以C++语言的应用领域更加广泛。
- C++ 语言可运行于多种平台上,如 Windows、MAC 操作系统及 UNIX 的多种版本。
- C++ 语言中加入了面向对象的概念,虽然 C 语言的语法绝大部分都被保留在 C++ 语言中,但 C++ 的程序结构与 C 语言的程序结构存在很大差别。C++ 语言对 C 语言做了很多改进,C++语言相对于C语言的最根本的变化是引进了类和对象的概念。
(1)基本的输入/输出
功能
|
C
语言中使用函数
|
C++
语言中提供类
|
C++
类中对象
|
运算符
|
---|---|---|---|---|
键盘输入
|
scanf()
|
输入流类
istream
|
cin
|
>>
|
屏幕输出
|
printf()
|
输出流类
ostream
|
cout
|
<<
|
- 在 C++ 中,可以使用流提取运算符 “>>” 从标准输入设备键盘取得数据。例如,语句 “cin>>x;” 从键盘获取输入数据并赋给变量 x 。使用 cin 可以获得多个来自键盘的输入值。
- cout 是一个标准输出流对象,使用流插入运算符 “<<” 向输出设备屏幕输出信息。
/* 示例:基本的输入输出 */
#include<iostream>
#include<string>
using namespace std;
int main( )
{
int oneInt1,oneInt2;
char strArray[20];
string str;
double oneDouble;
char oneChar='a';
cout<<"输入两个整型值,一个字符,一个字符串和一个浮点值,";
cout<<"以空格、Tab键或〈Enter〉键分隔:"<<endl;
cin>>oneInt1>>oneInt2>>oneChar>>strArray>>oneDouble;
str=strArray;
cout<<"输入的数据是:"<<endl; // endl 的作用是换行
cout<<"字符串是:\t\t"<<str<<endl // \t 是制表符 Tab
<<"两个整型值分别是:\t"<<oneInt1<<"和\t"<<oneInt2<<endl
<<"字符是:\t\t"<<oneChar<<"\n" // \n 是换行符,与 endl 效果相同
<<"浮点值是:\t\t"<<oneDouble<<endl;
return 0;
}
/* 假定,程序运行时输入:/*
10 20 g abc 25.5
/* 屏幕上会输出如下的运行结果:/*
输入的数据是:
字符串是: abc
两个整型值分别是: 10 和 20
字符是: g
浮点值是: 25.5
(2)头文件和命名空间
⚫ iostream 是 C++ 的 标准输入/输出流 。
- 当在程序中使用 cin 或 cout 时,必须在程序的最前面包含这个流。
- 如果还要使用其他的内容,那么需要包含其他的头文件。
- 每条 #include 指令仅可以包含一个头文件,如果需要包含多个头文件,则需要使用多条#include 指令。 【嵌入指令】
⚫ 在 C++ 中,头文件不再以 “.h” 结尾,以 “.h” 结尾的头文件是 C 语言中常用的头文件。
常用的头文件有以下一些:
- 标准输入输出流:<iostream>
- 标准文件流:<fstream>
- 标准字符串处理函数:<string>
- 标准数学函数:<cmath>
当使用 尖括号 时,C++ 编译器将 首先在 C++ 系统设定的目录中寻找要包含的文件 ,如果没有找到,再到指令中指定的目录中去查找。 采用双引号时,C++ 编译器在用户当前目录下或指令中指定的目录下寻找要包含的文件。
- 例如,要包含e:\myprog目录下的头文件 ex1.h,相应的语句如下:
#include "e:\myprog\ex1.h"
C++ 中为了避免名字定义冲突,特别引入了 “命名空间” 的定义,即 namespace 。命名空间的作用是为了消除同名引起的歧义。 using namespace std;定义一个命名空间的语法格式如下:namespace 命名空间名{命名空间内的各种声明(函数声明、类声明、……)}
(3)强制类型转换运算符
static_cast 用于将一种数据类型转换成另一种数据类型,使用格式如下:
【格式】static_cast<类型名>(表达式)
【功能】 其功能是把表达式转换为类型名所指定的类型【注意】 static_cast 也可以省略【示例】/* 示例(程序 1-1 ):基本的输入输出 */ #include<iostream> #include<string> using namespace std; int main( ) { int oneInt1,oneInt2; char strArray[20]; string str; double oneDouble; char oneChar='a'; cout<<"输入两个整型值,一个字符,一个字符串和一个浮点值,"; cout<<"以空格、Tab键或〈Enter〉键分隔:"<<endl; cin>>oneInt1>>oneInt2>>oneChar>>strArray>>oneDouble; str=strArray; cout<<"输入的数据是:"<<endl; // endl 的作用是换行 cout<<"字符串是:\t\t"<<str<<endl // \t 是制表符 Tab <<"两个整型值分别是:\t"<<oneInt1<<"和\t"<<oneInt2<<endl <<"字符是:\t\t"<<oneChar<<"\n" // \n 是换行符,与 endl 效果相同 <<"浮点值是:\t\t"<<oneDouble<<endl; return 0; } /* 假定,程序运行时输入:/* 10 20 g abc 25.5 /* 屏幕上会输出如下的运行结果:/* 输入的数据是: 字符串是: abc 两个整型值分别是: 10 和 20 字符是: g 浮点值是: 25.5
/* 以程序 1-1 中声明的变量为例,下面 4 种写法都是正确的:*/ oneInt2=static_cast<int>(oneDouble); //强制类型转换 oneInt2=int(oneDouble); //强制类型转换运算符的新形式 oneInt2=(int)oneDouble; //强制类型转换运算符的旧有形式 oneInt2=oneDouble; //自动类型转换
(4)函数参数的默认值
- C++ 语言规定,提供默认值时必须按从右至左的顺序提供,即有默认值的形参必须在形参列表的最后。
- 如果有某个形参没有默认值,则它左侧的所有形参都不能有默认值。
- 调用函数时,主调函数的实参与被调函数的形参按从左至右的顺序进行匹配对应。
【示例】 函数调用示例(一)
// 假设给出如下的函数声明: void func(int a,int b=2,int c=3); // 则下列函数调用中哪些是正确的?请解释原因。 func(1,22,333); func( ); func(10,20); func(5, ,9);
【分析】
- func(1,22,333); 是正确的,调用时给出了所有实参,且参数的类型也是匹配的。
- func( ); 是错误的,声明中参数 a 没有默认值,调用时必须给出实参值。
- func(10,20); 是正确的,实参表中的两个值 10 和 20 分别对应于函数声明中的形参 a 和 b ,参数 c 使用默认值 3。
- func(5, ,9); 是错误的,调用时给出的实参应该是连续排列的。
(5)引用和函数参数的传递
① 引用的定义
【定义】 引用相当于给变量起了一个别名。
- 变量对应于某个内存地址,如果给某个变量起了别名(不需要给它另开辟内存单元),相当于变量和这个引用都对应到同一地址。
- 程序中使用哪个名字都是允许的。
【格式】类型名 & 引用名 = 同类型的某变量名;
【示例】
int oneInt; int &aname=oneInt; // 声明引用
/* 示例:引用和函数参数的传递 */ #include<iostream> using namespace std; int main() { int oneInt=1; int &ref=oneInt; //ref 是 oneInt 的引用,ref 等价于 oneInt const int &refc=oneInt; //定义常引用 ref=2; //修改 ref 也即修改了 oneInt cout<<"oneInt="<<oneInt<<","<<"ref="<<ref<<endl; //输出 oneInt=2, ref=2 cout<<"refc="<<refc<<endl; //输出 refc=2 oneInt=3; //修改 oneInt 也即修改了 ref cout<<"ref="<<ref<<endl; //输出 ref=3 cout<<"refc="<<refc<<endl; //输出 refc=3 int & ref2=ref; //ref2 和 ref 都是 oneInt 的引用 cout<<"ref2="<<ref2<<endl //输出 ref2=3 //refc=5; //错误,不能使用常引用对所引用的变量进行修改 return 0; }
② 引用在函数中的使用
⚫ 在程序中不仅能定义变量的引用,还可以将引用用在函数中。
- 引用既可以作为函数的参数使用,也可以作为函数的返回值使用。
⚫ 在 C++ 中,函数调用时参数的传递有两种方式: 传值 和 传引用 。
- 传值:实际上是传递对象的值。
- 传引用:是传递对象的首地址值。
⚫ 如果函数的形参不是引用,那么调用时实参传递给形参通常采用的是传值的方式,即将实参的值拷贝给形参。
- 在函数执行过程中,都是对这个拷贝进行操作的,函数执行完毕返回后,形参的值并不拷贝回实参,也就是说函数内部对形参的改变不会影响到函数外实参的值。
⚫ 如果函数的形参是引用,则调用时实参传递给形参采用的是 传引用 的方式。
- 函数调用时,实参对象名传递给形参对象名,形参对象名就成为实参对象名的别名,即形参是对应实参的引用,它们是等价的,代表同一个对象,也可以看作是将实参的地址传递给了形参。
- 在函数内部对形参的操作,都是对这个地址的内容进行的,相当于对实参的值进行了操作。所以当函数执行完毕返回后,实参的变化被保留下来。
#include<iostream>
using namespace std;
void SwapValue(int a,int b)
{
int tmp;
tmp=a;
a=b;
b=tmp;
cout<<"在SwapVa1ue( )函数中:\t\ta="<<a<<",b="<<b<<endl;
}
void SwapRef(int & a,int & b) // a、b值互换
{
int tmp;
tmp=a;
a=b;
b=tmp;
cout<<"在SwapRef()函数中:\t\ta="<<a<<",b="<<b<<endl;
}
int main()
{
int a=10,b=20;
cout<<"数据交换前:\t\ta="<<a<<",b="<<b<<endl<<endl;
SwapValue(a,b);
cout<<"调用SwapVal()后:\t\ta="<<a<<",b="<<b<<endl<<endl;
a=10;
b=20;
SwapRef(a,b);
cout<<"调用SwapRef()后:\t\ta="<<a<<",b="<<b<<endl<<endl;
return 0;
}
#include<iostream>
using namespace std;
int oneX=10;
int oneY=20;
int & refValue(int & x)
{
return x;
}
int main()
{
refValue(oneX)=30; //返回值是引用,可以作为左值使用
cout<<"oneX="<<oneX<<endl; //输出 oneX=30
refValue(oneY)=40; //返回值是引用的函数调用表达式,可以作为左值使用
cout<<"oneY="<<oneY<<endl; //输出 oneY=40
return 0;
}
(6)const 与指针共同使用
const 修饰指针变量时,基本含义如下:
- 如果唯一的 const 位于符号 * 的左侧,表示指针所指数据是常量,数据不能通过本指针改变,但可以通过其他方式进行修改;指针本身是变量,可以指向其他的内存单元。
- 如果唯一的 const 位于符号 * 的右侧,表示指针本身是常量,不能让该指针指向其他内存地址;指针所指的数据可以通过本指针进行修改。
- 在符号 * 的左右各有一个 const 时,表示指针和指针所指数据都是常量,既不能让指针指向其他地址,也不能通过指针修改所指向的内容。
可以简单地记住 const 的修饰规则:
- const 修饰其左侧的内容
- 如果 const 是本行的第一个标识符,则它修饰其右侧的内容
#include<iostream>
using namespace std;
int main( )
{
int a1=3; //普通变量,a1=5 是正确的
const int a2=a1; //数据是常量的,a2=5 是错误的
int * a3=&a1; //普通指针指向普通变量,*a3=6 是正确的
const int * a4=&a1; //数据是常量的,普通指针 *a4=5 是错误的
int * const a5=&a1; //指针是常量的,不能修改指针,但 *a5=10 是正确的
int const * const a6=&a1; //数据是常量的,指针也是常量的
const int * const a7=&a1; //数据是常量的,指针也是常量的
return 0;
}
(7)内联函数
⚫ 为了避免这种频繁的函数调用与返回,C++ 语言引入了内联函数的概念。
- 使用内联函数,编译器在编译时并不生成函数调用,而是将程序中出现的每一个内联函数的调用表达式直接用该内联函数的函数体进行替换,就像整个函数体在调用处被重写了一遍一样。
- 很显然,使用内联函数会使最终可执行程序的体积增大。
- 这是以空间消耗节省时间开销。
⚫ 内联函数应该定义在前,调用在后,定义时只需在函数头返回值类型的前面加上 关键字 inline⚫ 内联函数主要 应用于代码量少的函数,频繁调用⚫ 如果函数体中有 循环语句 和 switch语句 则通常 不定义为内联函数
(8)函数的重载
函数重载:是指在程序的同一范围内声明几个功能类似的同名函数。
实现函数的重载必须满足下列条件之一:
- 参数表中对应的参数类型不同
- 参数表中参数个数不同
- 如果函数参数表中不同类型参数的次序不同,也符合上面所说的条件。
- 要注意的是,返回值类型不能用来区分函数,也就是说,如果两个函数的名字和参数表都是一样的,仅仅是返回值类型不同,则这两个函数不是重载的,编译器认为它们是重复定义,编译时会报错。
【注意】 所谓函数重载,是指在程序的同一范围内声明几个功能类似的同名函数。【示例】
- 例如,在同一个类中声明 3 个求两者中较大值的同名函数,如例 1-2 所示。
- 使用同一个函数名作为功能一样的函数的函数名,这也符合人们的习惯。
- 针对同名的函数,分别为其编写函数体,即可实现各自的功能。
/* 示例(例 1-2 )*/ #include<iostream> using namespace std; int biggerInt(int x,int y) //返回两个 int 型数中的较大者 { if(x>y) return x; else return y; } float biggerFloat(float x,float y) //返回两个 float 型数中的较大者 { if(x>y) return x; else return y; } double biggerDouble(double x,double y) //返回两个 double 型数中的较大者 { if(x>y) return x; else return y; } void main() { int a=5,b=8; cout<<biggerInt(a,b)<<endl; }
#include<iostream>
using namespace std;
int abs(int n)
{
return(n<0?-n:n);
}
float abs(float f)
{
if(f<0) f=-f;
return f;
}
double abs(double d)
{
if(d<0) return -d;
return d;
}
void main()
{
int a=-6;
cout<<abs(a)<<endl;
}
【注意】编译阶段,程序还没有执行,所以并不知道返回值是什么,更加确定不了它的类型,所以编译器并不能根据返回值确定该调用哪个函数。【示例】错误的重载函数float add(int, float); //将整数和浮点数相加,返回浮点数 int add(int, float); //将整数和浮点数相加,返回整数,错误!
【注意】 采用引用参数也不能区分函数【示例】错误的重载函数void print(double); void print(double&); //错误!
【示例】调用重载函数int xI=10,yI=20; float xF=30,yF=40; double xD=50,yD=60; cout<<bigger(xI,yI)<<endl; cout<<bigger(xF,yF)<<endl; cout<<bigger(xD,yD)<<endl;
【分析】根据函数重载的规则:
- bigger(xI,yI) 调用的是 int bigger(int,int) 函数
- bigger(x,yF) 调用的是 float bigger(float,float) 函数
- bigger(xD,yD) 调用的是 double bigger(double,double) 函数
【示例】调用函数时进行必要的类型提升
double bigger(double x,double y) { if(x>y) return x; else return y; } int xI=10,yI=20; float xF=30,yF=40; double xD=50,yD=60; cout<<bigger(xI,yF)<<endl;
【示例】调用重载函数时的二义性
- 若定义了重载函数 Sum( ),如下所示:
int Sum(int a,int b,int c=0); int Sum(int a,int b);
- 则以下函数调用语句将导致编译错误:
Sum(1,2);
【分析】因为编译器不知道是应该以 (1 , 2 , 0) 作为参数调用第一个 Sum( ) 函数,还是以 (1,2) 作为参数调用第二个 Sum( ) 函数,即 产生二义性 。在设计程序时,应该避免这种情况的发生。
(9)指针和动态内存分配
- 指针变量中保存的是一个地址,有时也称指针指向一个地址。
- 数组的长度是声明数组时指定的,在整个程序运行过程中通常是不变化的。C++ 语言不允许定义元素个数不确定的数组。
- 在 C++ 语言中,使用 new 运算符实现动态内存分配。
- 使用 new 运算符动态申请的内存空间,需要在使用完毕释放。C++ 提供了 delete 运算符,用来释放动态分配的内存空间。
- delete 运算符的基本用法如下: delete 指针;
- delete 运算符后面的指针必须是指向动态分配的内存空间的,否则运行时很可能会出错
【示例】指针变量中保存的是一个地址,有时也称指针指向一个地址,若有以下的定义:
int a=100,*p=&a;
【分析】
- 指针 p 指向整型变量 a,p 中保存 a 的地址,而不是值 100 。
- p 指向的地址中的值是 100。
- 地址与地址中的值不要混淆。
【示例】 数组的长度是声明数组时指定的,在整个程序运行过程中通常是不变化的。C++语言不允许定义元素个数不确定的数组。例如:
int n; int a[n]; //在有些编译环境下,这种定义是不允许的,因为 n 未知
【示例】 在 C++ 语言中,使用 new 运算符实现动态内存分配。
- 例如,可以写如下的语句:
p=new T;
其中,T 是任意类型名,p 是类型为 T* 的指针。
- 这样的语句会动态分配出一片大小为 sizeof(T) 字节的内存空间,并且将该内存空间的起始地址赋值给指针p。例如:
int * p; p=new int; *p=5;
第 2 行语句动态分配了有 4 个字节大小的内存空间,p 指向这个空间的首地址,之后通过指针 p 可以读写该内存空间。第 3 行语句是向这个空间中存入数值 5 。
- 使用 new 运算符还可以动态分配一个任意大小的数组:
p=new T[N];
其中,T 是任意类型名,p 是类型为 T* 的指针,N 代表数组 “元素个数” ,可以是任何的值为正整数的表达式。数组中元素的类型是 T 类型。这条语句动态分配了 N*sizeof(T) 个字节的内存空间,指针 p 指向这段空间的首地址。
【示例】动态分配整型数组
int * pArray; //指向数组的指针 int i = 5; pArray = new int [i*20]; //分配了 100 个元素的整型数组 pArray[0] = 20; //数组的第一个值 pArray [99] = 30; //数组的最后一个值
【分析】
- 数组的下标从 0 开始,含 n 个元素的数组的下标范围是从 0〜n-1。
- 超出这个范围的值都会导致数组下标越界。例如,上述代码中定义的数组 pArray ,当使用pArray[-1] 或是 pArray[100] 时,下标会越界。
- 不过在编译时,对于数组越界的错误并不会提示,而显示编译正确。运行时,会得到意料之外的结果。
【示例】 使用 new 运算符动态申请的内存空间,需要在使用完毕释放。C++提供了delete运算符,用来释放动态分配的内存空间。delete运算符的基本用法如下:
- delete 指针;
delete 运算符后面的指针必须是指向动态分配的内存空间的,否则运行时很可能会出错, 释放指针时出错示例如下:int oneInt=6; int * p=&ontInt; cout<<*p<<endl; delete p; //出错,p 是引用,不是动态分配的 int * q=new int; *q=8; cout<<*q<<endl; delete q; //正确,q 指向动态分配的空间
【分析】
- 指针 p 和 q 都指向一个整型变量,但指针 p 指向的空间并不是使用 new 运算符分配的,所以不能使用 delete 释放
- 而指针 q 指向的空间是使用 new 分配的,所以使用完毕,通过 delete 进行释放
- 如果是使用 new 运算符动态分配了一个数组,那么释放该数组时,语句为:delete [ ] 指针;
- 例如,释放上述代码中分配的数组空间的语句是 “delete [ ] pArray;”
(10)用 string 对象处理字符串
- C++ 标准模板库中提供了 string 数据类型,专门用于处理字符串。
- string是一个类,这个类型的变量称为 “string对象” 。
① string 对象的使用
要在程序中使用 string 对象,必须在程序中包含头文件 string ,即在程序的最前面,要加上如下语句:#include<string>
② string 对象的声明
声明一个 string 对象,与声明普通变量是类似的,格式如下:string 变量名;
【示例】
- 声明 string 对象 str1 ,值为空
- 声明 string 对象 city ,并使用字符串常量进行初始化
- 声明 string 对象 str2 ,并使用字符串变量进行初始化
string str1; //声明 string 对象 str1,值为空 string city="Beijing"; //声明 string 对象 city,并使用字符串常量进行初始化 string str2=city; //声明 string 对象 str2,并使用字符串变量进行初始化 cout<<"str1="<<str1<<"."<<endl; cout<<city<<","<<str2<<endl;
【示例】使用字符数组对 string 变量进行初始化
char name[ ]="C++程序"; string s1=name;
【示例】声明一个 string 对象数组,即数组中每个元素都是字符串
string citys[ ]={"Beijing","Shanghai","Tianjin","Chongqing"}; cout<<citys[1]<<endl; //输出 Shanghai,数组下标从 0 开始 cout<<sizeof(citys)/sizeof(string)<<endl; //输出数组元素个数
【分析】
- 最后一行语句将输出数组元素个数。
- citys 是 string 对象数组
- sizeof(citys) 是整个数组占用的空间大小
- sizeof(string) 是每个 string 对象的大小
- 所以 sizeof(citys) / sizeof(string) 表示的是数组元素个数
③ string 对象的操作
【说明】 string 对象可以使用 cin 和 cout 进行输入和输出,实际上,到目前为止,已经使用了很多这样的示例。【示例】string s1,s2; cin>>s1>>s2; cout<<s1<<","<<s2<<endl;
【说明】
- string对象之间可以互相赋值,也可以用字符串常量和字符数组的名字对string对象进行赋值。
- 赋值时不需要考虑被赋值的对象是否有足够的空间来存储字符串。
【示例】
string s1,s2="OK"; s1="China"; s2=s1; // s1 和 s2 表示的字符串不等长,赋值后 s2 的内容和 s1 相同 cout<<"s1="<<s1<<"s2="<<s2<<endl;
#include<iostream>
#include<string>
using namespace std;
void main()
{
string s1, s2;
s1="C++程序";
s2=s1;
string s3;
cout<<"s3= "<<s3<<endl; //输出 s3=
s3=s1+s2;
cout<<s1+s2<<endl; //输出 C++程序C++程序
cout<<"s3="<<s3<<endl; //输出 s3=C++程序C++程序
s3+="de";
cout<<"s3="<<s3<<endl; //输出 s3=C++程序C++程序de
bool b=s1<s3; //b 为 true
cout<<"bool="<<b<<endl; //输出 bool=1
char c=s1[2]; //c 为 '+',下标从 0 开始计算
cout<<"c="<<c<<endl; //输出 c=+
cout<<s1[2]<<endl; //输出 +
char arrstr[]="Hello";
s3=s1+arrstr;
cout<<s3<<endl; //输出 C++程序Hello
}
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str; //未初始化,空串
if(str.empty())
cout<<"str is NULL."<<",length="<<str.length()<<endl;
else
cout<<"str is not NULL."<<endl;
str=str.append("abcdefg");
cout<<"str is "<<str<<",size="<<str.size()<<endl;
const char *p=str.c_str();
cout<<"p="<<p<<endl;
cout<<"find:"<<str.find("de",0)<<endl; //查找成功,3
cout<<"find:"<<str.find("de",4)<<endl; //查找失败
string str1=str.insert(4,"123");
cout<<str1<<endl;
return 0;
}
三、C++ 语言的程序结构
- C++ 程序以 .cpp 作为文件扩展名,文件中包含若干个类和若干个函数。
- 程序中必须有且仅有一个主函数 main( ),这是程序执行的总入口。
- 主函数也称为主程序。
- 程序从主函数 main( ) 的开始处执行,主函数可以在任何地方出现,按照其控制结构,一直执行到结束。
主函数中可以调用程序中定义的其他函数,但其他函数不能调用主函数。 主函数仅是系统为执行程序时所调用的。
程序的结束通常是遇到了以下两种情形之一:
- 在主函数中遇到 return 语句
- 执行到主函数最后面的括号 }
C++ 程序中,仍沿用 C 语言的注释风格,即注释有以下两种形式:
- 多行注释:从 /* 开始,到 */ 结束,这之间的所有内容都视作注释
- 单行注释:从 // 直到行尾,都是注释