零基础学C++之进阶篇一

零基础学C++之进阶篇一

数组、指针、引用

数组是有序数据的集合,可以减少对同样类型变量的声明;指针是可以操作内存数据的变量;引用是变量的名别;数组的首地址可以看作是指针,通过指针可以操作数组,指针和引用在函数的参数传递时可以互相替代。指针是一把双刃剑,既能提升程序的效率,也能给程序带来意想不到的灾难。

一维数组

一维数组的声明

在程序设计中,将同一数据类型的数据按一定形式有序的组织起来,这些有序数据的集合称为数组。一个数组有一个统一的数组名,可以通过数组名和下标来唯一确定数组中的元素。
一维数组的声明形式如下:

数据类型 数组名[常量表达式]

常量表达式表示元素的个数,即数组的长度,定义数组的常量表达式不能是变量,数组的大小不能动态定义。

一维数组的引用

数组引用的一般形式如下:

数组名[下标]

数组元素的下标起始值为0,不是1。

一维数组的初始化

数组元素初始化的方式有两种,一种是对单个元素逐一赋值,另一种是使用聚合方式赋值。
(1)单一数组元素赋值
a[0]=0就是对单一数组元素赋值,也可以通过变量控制下标的方式进行赋值。
(2)聚合方法赋值
数组不仅可以逐一对数组元素赋值,还可以通过大括号进行多个元素赋值。

int a[12]={1,2,3,4,5,6,7,8,9,10,11,12};
int a[]={1,2,3,4,5,6,7,8,9,10,11,12};
int a[12]={1,2,3,4,5,6,7};

二维数组

二维数组的声明

二维数组声明的一般形式为:

数据类型 数组名[常量表达式1][常量表达式2]

一维数组描述的是一个线性序列,二维数组则描述的是一个矩阵,常量表达式1代表行数,常量表达式2代表列数。

二维数组的引用

二维数组元素的引用形式为:

数组名[下标][下标]

二维数组的初始化

二维数组元素初始化和一维数组相同,也分为单个元素逐一赋值和使用聚合方法赋值。如:

a[0][1]=12;
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

实例01 交换二维数组的行和列

#include <iostream>
#include <iomanip>
using namespace std;
void fun(int array[3][3])
{
	for(int i=0;i<3;i++)
	{
		for(int j=0; j<3;j++)
		{
			t=array[i][j];
			array[i][j]=array[j][i];
			array[j][i]=t;
		}
	}
}
void main()
{
	int array[3][3]={{1,2,3},{4,5,6},{7,8,9}};
	cout << "convert front" << endl;
	for(int i =0; i < 3;i++)
	{
		for(int j=0;j<3;j++)
		{
			cout << setw(7) << array[i][i];
		}
		cout << endl;
	}
	fun(array);
	cout << "convert front" << endl;
	for(int i =0; i < 3;i++)
	{
		for(int j=0;j<3;j++)
		{
			cout << setw(7) << array[i][i];
		}
		cout << endl;
	}
}

字符数组

用来存放字符数据的数组是字符数组,字符数组中的一个元素存放一个字符,字符数组具有数组的共同属性。字符数组赋值的方式与数组赋值相同,但聚合方式只能在数组声明的时候使用,字符数组不能给字符数组赋值;字符数组常作为字符串使用,作为字符串要有字符串结束符"\0"。
(1)字符串处理函数

  • strcat()函数
    字符串连接函数strcat格式如下:

strcat(字符数组名1,字符数组名2)

把字符数组2中的字符串连接到字符数组1中字符串的后面,并删去字符串1后的字符串结束标志“\0”。
实例02 字符串的连接操作

#include <iostream>
#include <string>
using namespace std;
void main()
{
	char str1[30],str2[20];
	cout << "please input string1:" <<endl;
	gets(str1);
	cout << "please input string2:" << endl;
	gets(str2);
	strcat(str1,str2);
	cout << "Now the string1 is: " << endl;
	puts(str1);
}
  • strcpy()函数
    字符串复制函数strcpy()格式:

strcpy(字符数组1,字符数组2);

说明:
①字符数组1应有足够的长度,否则不能全部装入所复制的字符串。
②字符数组1必须写成数组名形式,字符数组2可以是字符数组名,也可以是一个字符串常量。
实例03 字符串的复制操作

#include <iostream>
#include <string>
using namespace std;
void main()
{
	char str1[30],str2[20];
	cout << "please input string1:" <<endl;
	gets(str1);
	cout << "please input string2:" << endl;
	gets(str2);
	strcpy(str1,str2);
	cout << "Now the string1 is: " << endl;
	puts(str1);
}
  • strcmp()函数
    字符串比较函数strcmp()格式如下:

strcmp(字符数组名1,字符数组名2);

按照ASCII码顺序比较两个数组中的字符串,并由函数返回比较结果:
字符串1=字符串2,返回0;
字符串1>字符串2,返回正数;
字符串1<字符串2,返回负数;

实例04 字符串的比较操作

#include <iostream>
#include <string>
using namespace std;
void main()
{
	char str1[30],str2[20];
	cout << "please input string1:" <<endl;
	gets(str1);
	cout << "please input string2:" << endl;
	gets(str2);
	int res=strcmp(str1,str2);
	if(res == 0)
	{
		cout << "str1 = str2" << endl;
	}else if(res > 0)
	{
		cout << "str1 > str2" << endl;
	}else
	{
		cout << "str1 < str2" << endl;
	}
}
  • strlen()函数
    获取字符串长度函数strlen()格式如下:

strlen(字符数组名)

获取字符串的实际长度(不含字符串结束标志“\0”),函数返回值为字符串的实际长度。
实例05 获取字符串长度

#include <iostream>
#include <string>
using namespace std;
void main()
{
	char str1[30],str2[20];
	cout << "please input string1:" <<endl;
	gets(str1);
	cout << "please input string2:" << endl;
	gets(str2);
	cout << "The length of string1 is:" << strlen(str1) << endl;
	cout << "The length of string2 is:" << strlen(str2) << endl;
}

指针

变量与指针

指针是一种数据类型,它是一个专门用来存放地址的变量,变量的指针主要指变量在内存中的地址。
声明指针的一般形式如下:

数据类型标识符 *指针变量名

指针可以在声明的时候赋值,也可以后期赋值。如:

int i = 100;
int *p = &i;
或者
int *p;
p=&i;

指针变量名是p,而不是p;p=&i的意思是取变量i的地址赋给指针变量p;指针变量不可以直接赋值,也不能把p当变量使用。

指针运算符和取地址运算符

”和“&”是两个运算符,“”是取值运算符,“&”是取地址运算符。
实例06 输出指针对应的数值

#include <iostream>
using namespace std;
void main()
{
	int a=100;
	int *p=&a;
	cout << "a=" << a <<endl;
	cout << "*p=" << *p << endl;
}
指针运算

指针变量存储的是地址值,对指针做运算就等于对地址做运算。
实例07 输出指针运算的地址值

#include <iostream>
using namespace std;
void main()
{
	int a =100;
	int *p=&a;
	pringf("address :%d\n",p);
	p++;
	pringf("address :%d\n",p);
	p--;
	pringf("address :%d\n",p);
	p--;
	pringf("address :%d\n",p);
}
指向空的指针和空类型指针

指针可以指向任何数据类型的数据,包括空类型(void),定义如下:

void *p;

空类型指针可以接受任何类型的数据,当使用它时,可以将其强制转化为所对应的数据类型。
实例08 空类型指针的使用

#include <iostream>
using namespace std;
void main()
{
	int *p=NULL;
	int i=4;
	p=&i;
	float f=3.33f;
	void *pV=NULL;
	cout << "依次赋值给空指针"  << endl;
	pV=p;
	cout << "pV = p -------" << *(int *)pV << endl;
	cout << "pV = p -------转为float类型指针" << *(float *)pV << endl;
	pV = &f;
	cout << "pV = &f -------" << *(float *)pV << endl;
	cout << "pV = &f -------转为int类型指针" << *(int *)pV << endl;
}
指向常量的指针和指针常量

同其他数据类型一样,指针也有常量,使用const关键字形式如下:

int i = 9;
int * const p = &i;
*p = 3;

将关键字const放在标识符前,表示这个数据本身是常量,而数据类型是int*,即整型指针。与其他常量一样,指针常量必须初始化。无法改变它的内存指向,但可以改变它指向内存的内容。
若将关键字const放到指针类型的前方,形式如下:

int i = 9;
int const* p=&i;

这是指向常量的指针,虽然其所指向的数据可以通过赋值语句进行修改,但是通过该指针修改内容的操作是不被允许的。
当const以如下形式使用时:

int i = 9;
int const* const p = &i;

该指针是一个指向常量的指针常量,既不可以改变它的内存指向,也不可以通过它修改指向内存的内容。

指针与数组

指针与一维数组

系统需要提供一定量连续的内存来存储数组中的各个元素,内存都有地址,指针变量就是存放地址的变量,如果把数组的地址赋给指针变量,就可以通过指针变量来引用数组。引用数组元素有两种方法:下标法和指针法。

  • 下标法

int a[10]
int *p;
p=&a[0];

  • 指针法

int a[10];
int *p;
p=a;

指针与二维数组

使用指针引用二维数组和引用一维数组相同,首先声明一个二维数组和一个指针变量:

int a[4][3];
int *p;

a[0]是二维数组第一个元素的地址,可以将改地址直接赋值给指针变量。

p=a[0];
或者
p=&a[0][0];

指针与字符数组

字符数组是一个一维数组,使用指针同样也可以引用字符数组,引用字符数组的指针为字符指针,字符指针就是指向字符型内存的指针变量,其一般的定义语句如下:

char *string=“hello world”;

实例09 通过指针偏移连接字符串

#include <iostream>
using namespace std;
void main()
{
	char str1[50],str2[30],*p1,*p2;
	p1=str1;
	p2=str2;
	cout << "please input string1:" << endl;
	gets(str1);
	cout << "please input string2: "<< endl;
	gets(str2);
	while(*p1!='\0')
		p1++;
	while(*p2!='\0')
		*p1++=*p2++;
	*p1='\0';
	cout << "The new string is :" << endl;
	puts(*p1);
}

指针在函数中的应用

传递地址

实例10 通过传递地址交换两个变量值

#include <iostream>
using namespace std;
void swap(int *a,int *b)
{
	int tmp;
	tmp=*a;
	*a = *b;
	*b=tmp;
}
void main()
{
	int x,y;
	int *p_x,*p_y;
	cout << "input two number" << endl;
	cin >> x;
	cin >> y;
	p_x=&x;
	p_y=&y;
	cout << "按指针传递参数交换" << endl;
	swap(p_x,p_y);
	cout << "x=" << x << endl;
	cout << "y=" << y << endl;
}
指向函数的指针

指针变量也可以指向一个函数,一个函数在编译时被分配一个入口地址,这个函数入口地址就称为函数的指针,可以用一个指针变量指向函数,然后通过该指针变量调用此函数。
定义指针函数的一般形式为:

类型名 *函数名(参数列表);

例如,定义一个具有两个参数和一个返回值的函数的指针:

int sum(int x,int y);
int *a(int,int);
a=sum;

函数指针能指向返回值与参数列表的函数,当使用函数指针时形式如下:

int c,d;
(*a)(c,d);

实例11 使用指针函数计算平均值

#include <iostream>
#include <iomanip>
using namespace std;
int avg(int a,int b);
void main()
{
	int ia,ib,iavg;
	ia=10;
	ib=30;
	int (*pfun)(int,int);
	pfun=avg;
	iavg=(*pfun)(ia,ib);
	cout << "avg:" << iavg << endl;
}
int avg(int a,int b)
{
	return (a+b)/2;
}
从函数中返回指针

定义一个返回指针类型的函数形式如下:

int *function(param list)
{
	int *p;
	......;
	return p;
}

指针数组

数组中的元素均为指针变量的数组称为指针数组,一维指针数组的定义形式如下:

类型名 *数组名[数组长度]

指针数组中的数组名也是一个指针变量,该指针变量未指向指针的指针。
p是一个指针数组,它的每一个元素是一个指针数据,指针数组p的第一个值是变量a的地址,指针数组中的元素可以使用指向指针的指针来引用,如:

int **p;

引用

引用概述

引用是一种隐式指针,它为对象建立一个别名,通过操作符&来实现。&是取地址操作符,通过它可以获得地址。
引用的形式如下:

数据类型 & 表达式;

引用的使用说明如下:
(1)一个C++引用被初始化后,无法使用它再去引用另一个对象,它不能被重新约束。
(2)引用变量知识其他对象的别名,对它的操作与原对象的操作具有相同作用。
(3)指针变量与引用有两点区别:一是指针是一种数据类型,二引用不是一个数据类型。二是指针变量和引用变量都用例指向其他变量,但指针变量使用的语法要复杂一些,而在定义了引用变量后,其使用方法和普通变量相同。
(4)引用应该初始化,否则会报错。

使用引用传递参数

实例12 通过引用交换两个变量值

#include <iostream>
using namespace std;
void swap(int &a,int &b)
{
	int tmp;
	tmp=a;
	a = b;
	b=tmp;
}
void main()
{
	int x,y;
	int *p_x,*p_y;
	cout << "input two number" << endl;
	cin >> x;
	cin >> y;
	cout << "按指针传递参数交换" << endl;
	swap(x,y);
	cout << "x=" << x << endl;
	cout << "y=" << y << endl;
}
数组作为函数参数

实例13 获取命令参数

#include <iostream>
using namespace std;
void main(int argc,char *argv[])
{
	cout << "The list of parameter:" << endl;
	while(argv>1)
	{
		++argv;
		cout << *argv << endl;
		--argc;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值