初学C++

  • Post author:
  • Post category:其他



目录


字符串的处理——string类型


名字空间的定义及使用


相比C语言函数相关的改进


引用的定义与应用


动态内存空间管理


异常处理



字符串的处理——string类型

string s4 {8, 'A'};

定义字符串s4的初值是8个A

cout << "s4=" << s4 << "s4的长度是:" << s4.length() << endl;

串名.length()     用于求串的长度

s2 = s3 + ' ' + s4;

串名+串名       可以实现字符串之间的联结

s3.insert(7, "&teacher");

表示向s3的7下标出插入&teacher

s3.replace(2, 4, "ar");

表示将s3从

2下标开始长度为4

的子串替换成ar

s1 = s3.substr(6, 7);

表示将s3从下标

6开始长度为7

的字串

赋值

给s1

int pos = s3.find(s1);

表示在s3中查询s1是否存在,

若存在则返回s1在s3中第一个字符的下标

s3.erase(5, 8);

表示删除s3从

5下标开始的8个字符

bool f = s1 > s4;

关系运算符可以比较字符串的大小

关系运算符里的两个函数:


boolalpha

将布尔值显示为ture或者flase


noboolalpha

将布尔值显示为0或者1


名字空间的定义及使用


名字空间的定义:

namespace one
{
	const int M = 200;
	int inf = 10;
	int x;
}

namespace 名字空间名称{…;…;}//最后大括号外面不用加分号


使用名字空间中的内容:

F1:名字空间名称::局部内容名

如:one::inf*=2;

F2:using namespace 名字空间名称;//作用是以一个申明

如:using namespace one;

F3:using 名字空间名称::局部内容名;

如:using one ::x;


相比C语言函数相关的改进


1.扩大全局变量的作用域

在C语言中,全局变量的作用域虽然从定义开始到程序结束,但是在同名局部变量作用域内,该全局变量不可见,C++对此进行了改进。

可在全局变量前加上域解析符“::”来访问被隐藏的全局变量。

示例如下:

::sum += sum;


2.形式参数可带有默认值

在C语言中,调用函数时实参必须与形参的个数保持相等,没有实参形参就无法得到相应的值。

但是在C++中允许函数原型申明中为一个或多个形参指定默认参数值,这样在调用函数时,可以不必提供实参,当然如果提供了实参那么还是将实参带到函数里,所以在C++中实参的个数小于等于形参。

示例如下:

void Fun(int i, int j = 5, int k = 10);
Fun(20);


注意:

1.默认参数值如果在函数原型中已经给出了,那么在函数定义首部不必再次出现。如果原型中没有给出,那么函数定义首部可以出现。

2.默认参数值的给定一定是

从右往左

的,所以诸如void Fun(int i, int j , int k = 10);

void Fun(int i=1, int j = 5, int k = 10);都是对的.但是像void Fun(int i, int j = 5, int k );就是错误的了。

3.实参提供的顺序是

从左往右


3.函数重载

在C语言中,同一作用域范围内函数名必须是唯一的。这就造成了完成同一或相似功能的函数必须定义不同的名称,增加了记忆负担。。

在C++中对于功能完全相同或类似的,只在

形参的个数,类型和顺序

存在差异的函数,可以用相同的函数名来命名,这种情况被称为

重载

下面通过一段代码来对重载进行示例:

#include<iostream>
using namespace std;

int square(int x)
{
	return x*x;
}

float square(float x)
{
	return x * x;
}

double square(double x=1.5)
{
	return x * x;
}

int main()
{
	cout << "square()=" << square() << endl;
	cout << "square(10)=" << square(10) << endl;
	cout << "square(2.5f)=" << square(2.5f) << endl;
	cout << "square(1.1)=" << square(1.1) << endl;
	return 0;
}

运行结果如下:

square()=2.25

square(10)=100

square(2.5f)=6.25

square(1.1)=1.21


注意:

1.重载函数必须具有

相同的函数名

,但是在

形参的个数,类型,顺序的一个或几个方面必须存在不同

,返回值不是区分重载函数的要素。

例如:void Fun(int)与int Fun(int )是错误的重载函数,它们的形参一样,仅返回值不同,不符合要求。

2.在函数调用时,如果给出的实参与形参的类型不相符,编译器会自动进行类型转化。


引用的定义与应用

引用是C++新增的概念,用来为变量起别名,在声明时通过“&”来标记。

格式如下:数据类型 &引用名=一个已定义的变量名

代码演示:

int x=5;
int &r=x;


说明:

1.引用被声明以后就可以像普通变量一样使用,使用时不用再带“&”符号。

2.引用只是一个变量的别名,所以系统不会为它另外开辟新的空间,像上面代码中r和x占用的是同一段空间。

2.并不是任何类型的数据都可以由引用,像void & r=x;    int &&r=x;    int &*p=x;     int &ra[10];      都是错误的。(即不能建立void类型的引用,引用的引用,指向引用的指针,引用数组)


引用作为形参

在C++中引用最常用的用途是作为函数的形参,这样就可以通过

对引用的访问和修改达到对实参进行操作的效果

与引用形参对应的实际参数只能是变量,而不能是常量或者表达式。

可以在引用参数之前

加上const修饰使其变成常引用

,一旦修改常引用形参,编译器就会报错,这在语法上保证了实参的安全性。


引用与指针的比较

有一种观点认为“引用是能自动间接引用的一种指针”。

以交换值的函数演示两者之间的区别:

void swap(int &x,int &y)
{
	int t = x;
	x = y;
	y = t;
}

void swap(int* x, int* y)
{
	int t = *x;
	*x = *y;
	*y = t;
}

上面这个函数中x,y不会另外占用空间,与实参共享空间。

下面这个函数x,y需要额外占用空间,获得的是实参的地址。


引用作为返回值

原型声明如下:

类型名 & 函数名 (形参表)

int &Fun(const int &x,int &y,int z)

它可以作为赋值的左值使用如:Fun(a,b,c)=20;

说明:

return后面只能是变量,而不能是常量或表达式,因为只有变量才能作左值。

return后面变量的内存空间在本次函数调用结束后仍要存在,所以自动局部变量不能作为返回值。

return后面的变量不能是常引用,这样作为左值时会改变它的值,编译器会报错。


动态内存空间管理

在C语言中通过malloc,calloc函数申请动态内存空间,free来释放空间。

在C++中则通过new和delete来实现这些操作。(new和delete是运算符而不是函数)


用new申请动态内存空间:

比较C与C++在申请动态空间上的区别:

申请一个int型动态的变量:

int *ptr = (int*)
	malloc(sizeof(int));//C

ptr = new int;//C++

申请N个元素的动态一维数组:

ptr = (int*)
		malloc(N * sizeof(int));//C

ptr = new int[N];//C++

申请N行M列的动态二维数组:

int* q = (int**)
		malloc(N * sizeof(int*));
	for (i = 0; i < N; i++)
		q[i] = (int*)
		malloc(M * sizeof(int));//C

q = new int* [N];
	for (i = 0; i < N; i++)
		q[i] = new int[M];//C++


用delete释放动态内存空间:

示范代码如下:

	ptr = new int;
	delete ptr;

	ptr = new int[N];
	delete[]ptr;

	q = new int* [N];
	for (i = 0; i < N; i++)
		q[i] = new int[M];
	for (i = 0; i < N; i++)
		delete[]q[i];
	delete[]q;

下面通过一个例子加深对其的了解:

生成N个0-99的随机整数,统计其中奇数的个数。用一个动态一维数组存放N个随机数,用一个动态整形变量存放统计结果。

#include<iostream>
#include<iomanip>
#include<cmath>
#include<ctime>
using  namespace std;

const int N= 30;
int main()
{
	int* p, * sum, i;
	sum = new int(0);
	p = new int[N];
	if (p == NULL)
	{
		cout << "allocation failure!\n";
		return 0;
	}
	srand(time(NULL));
	for (i = 0; i < N; i++)
	{
		p[i] = rand() % 100;
		if (p[i] % 2)
			(*sum)++;
	}
	for (i = 0; i < N; i++)
	{
		cout << setw(4) << p[i];
		if ((i + 1) % 10 == 0)
			cout << endl;
	}
	cout << "The number of odd is:" << *sum << endl;
	delete[]p;
	delete sum;
	return 0;
}

上面申请动态内存空间用sum=new int (0)而不是sum=new int。因为后面这个语句得到的sum的初值是随机值,所以前面这个语句给sum赋了初值0,就保证了最后结果的正确性。


异常处理

程序中的

错误

可分为语法错误和运行错误。语法错误包括编译错误和链接错误,运行错误是编译,链接通过后,程序在运行时出现的错误。


异常

指的是不同,即与期待的结果不同,它是一种错误,但不是上述中的错误。例如某个月份是13,就可以认为是异常。

在C++中,异常处理通过以下三步来实现

1.检查异常(使用try语句块)

2.抛出异常(使用throw语句块)

3.捕捉异常(使用catch语句块)

下面通过代码来进行演示:

#include<iostream>
using namespace std;

int divide(int x, int y)
{
	if (y == 0)throw y;
	return x / y;
}

int main()
{
	int a = 10, b = 5, c = 0;
	try
	{
		cout << "a/b=" << divide(a, b) << endl;
		cout << "b/a=" << divide(b, a) << endl;
		cout << "a/c=" << divide(a, c) << endl;
		cout << "c/a=" << divide(c, a) << endl;
	}
	catch (int)
	{
		cout << "except of divide zero" << endl;
	}
	cout << "calculate finished" << endl;
	return 0;
}


注意:


1.try-catch语句必须同时出现,并且try在前,catch在后。

2.try和catch块之间不能有其他的语句。

2.只能有一个try块,但是可以有很多个catch块。



版权声明:本文为WSFREEWS原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。