C++程序设计基础(六)---数组、指针、字符串

// 第六章数组指针字符串
/*
6.1 数组
1、数组的声明与使用
声明的一般形式:数据类型 标识符[常量表达式][常量表达式]
例如:int b[5][3];表示b为一个5行3列的整形数组

数组的使用形式:
数组名[下标表达式1][下标表达式2]。。。

//6_1.cpp
#include
using namespace std;
int main()
{
int a[10],b[10];
for (int i=0;i<10;i++)
{
a[i]=i*2-1;
b[10-i-1]=a[i];
}
for (int i=0;i<10;i++)
{
cout<<“a[”<<i<<"]"<<a[i]<<" “;
cout<<“b[”<<i<<”]"<<b[i]<<endl;
}
return 0;
}
2、数组的存储与初始化
数组的存储:数组元素在内存中是顺序、连续存储的。
例如,int m=[2][3]的存储模式为:
m[0][0]m[0][1]m[0][2]m[1][0]m[1][1]m[1][2]
数组的初始化就是在声明数组时给部分或全部元素赋初值。
例如 int a[3]={1,1,1};
int a[2][3]={1,0,0,0,1,0}等价于int a[][3]={1,0,0,0,1,0}等价于int a[2][3]={{1,0,0},{0,1,0}};
数组也可以被声明为常量
const float fa[3]={1.0,2.0,3.0};
3、数组作为函数参数
数组元素和数组名都可以作为函数的参数以实现函数间数据的传递和共享
使用数组名传递数据时,传递的是地址。
//6_2.cpp 使用数组名作为函数参数
#include
using namespace std;
void rowSum(int a[][4],int nRow)
{
for (int i=0;i<nRow;i++)
{
for(int j=1;j<4;j++)
a[i][0]+=a[i][j];
}
}
int main()
{
int table [3][4]={{1,2,3,4},{2,3,4,5},{3,4,5,6}};
for (int i=0;i<3;i++)
{
for (int j=0;j<4;j++)
cout<<table[i][j]<<" ";
cout<<endl;
}
rowSum(table,3);
for (int i=0;i<3;i++)
cout<<“Sum of row”<<i<<“is”<<table[i][0]<<endl;
return 0;
}

4、对象数组
声明一个一维对象数组的语句形式是:类名 数组名[常量表达式];
与基本类型数组一样,在使用对象数组时也智能引用单个数组元素。每个数组元素都是一个对象,通过这个对象便可以访问到
它的公有成员,一般形式是:
数组名[下标表达式].成员名
//6_3.cpp对象数组应用举例
//Point.h
#ifndef _POINT_H
#define _POINT_H
class Point{ //类的定义
public: //外部接口
Point();
Point(int x,int y);
~Point();
void move(int newX,newY);
int getX() const{return x;}
int getY() const{return y;}
static void showCount();
private:
int x,y;
};
#endif

//Point.cpp
#include
#include “Point.h”
using namespace std;

Point::Point()
{
x=y=0;
cout<<“Default Constructor called.”<<endl;
}
Point::Point(int x,int y):x(x),y(y)
{
cout<<“Constructor called.”<<endl;
}

Point::~Point()
{
cout<<“Destructor called.”<<endl;
}
void Point::move(int newX,int newY)
{
cout<<“Moving the point to(”<<newX<<","<<newY<<")"<<endl;
x=newX;
y=newY;
}

//main.cpp
#include “Point.h”
#include
using namespace std;
int main()
{
cout<<“Entering main…”<<endl;
Point a[2];
for (int i=0;i<2;i++)
a[i].move(i+10,i+20);
cout<<“Exiting main…”<<endl;
return 0;
}
"

6.2 指针
1、内存空间的访问形式
存储单元组成了内存,且内存单元按照一定的规则编号,这个编号就是存储单元的地址。地址编码的基本单位是字节,每个字节由8个二进制位组成。
C++中如何利用北村单元存取数据呢?
一是通过变量名,二是通过地址。
2、指针变量的声明
指针变量是用来存放内存单元地址的。
内存的访问形式有两种:一是直接访问,通过变量名进行访问,二是间接访问,通过指针访问
声明指针的语法形式是:
数据类型 * 标识符
例如:int * a;
3、与地址相关的运算和&
:指针运算符,表示获得指针所指向的变量的值,即一个地址中存储的值
&:地址运算符,表示获得一个地址
4、指针的赋值
存储类型 数据类型 * 指针名=初始地址;
指针名=地址;
//6_5.cpp指针的定义、赋值与使用
#include
using namespace std;
int main()
{
int i;
int * ptr=&i;
i=10;
cout << “i=” << i << endl;
cout << "对指针变量ptr使用
指针运算符得到的是ptr存储的内存地址中的数值,则
ptr= " << ptr << endl;
cout << “对变量i进行地址运算,&i得到i的地址为:” << &i << endl;
cout << “指针变量ptr存储的地址:” << ptr << endl;
return 0;
}
需要注意的几点:
— const int p1=&a;
int
const p1=&a;
是不同的两种操作,第一种p1可以改变,但是
p1不能改变
第二种,p1=&b是错误的操作
-------void类型的指针
可以存储任何类型的对象地址。
//6_6.cpp void类型的指针的使用
#include
using namespace std;
int main()
{
//void voidObject;
void *pv;
int i=5;
pv=&i;
int pint=static_cast<int>(pv);
cout<<"*pint="<<*pint<<endl;
return 0;
}

5、指针运算
指针是一种数据类型。可以进行运算
可以进行加减运算,但是运算规则比较特殊,例如指针变量p1和整数n1
p1+n1表示指针p1当前所指位置后方第n1个数的地址,p1-n1表示指针p1当前所指向位置前方第n1个数的地址。
*(p1+n1)表示p1当前所指位置后方第n1个数的内容,也可以写作p1[n1],
0专用于表示空指针,也就是一个不指向任何有效地址的指针,int p;p=0;
空指针也可以用NULL来表示,int
p=NULL;
6、用指针处理数组元素
//6_7.cpp 设有一个int型数组a,有10个元素。用3中方法输出各元素。
//6_7_1.cpp
#include
using namespace std;
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,0};
for (int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}

//6_7_2.cpp 使用数组名和指针运算
#include
using namespace std;
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,0};
for (int i=0;i<10;i++)
cout<<*(a+i)<<" “;
cout<<endl;
return 0;
}
//6_7_3.cpp使用指针变量
#include
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,0};
for (int *p=a;p<(a+10);p++)
cout<<*p<<” ";
cout<<endl;
return 0;
}

7、指针数组
如果一个数组的每个元素都是指针变量,这个数组就是指针数组。
声明一维指针数组的语法形式为:
数据类型 * 数组名[下标表达式];
下标表达式指出数组元素的个数,数据类型确定每个元素指针的类型,数组名是指指针数组的名称,同时也是这个数组的首地址。例如:int *pa[3];
声明了一个int类型的指针数组pa,其中有3各元素,每一个元素都是一个指向int类型数据的指针
//6_8.cpp利用指针数组输出单位矩阵
#include
using namespace std;
int main()
{
int line1[]={1,0,0};//定义数组,矩阵的第一行
int line2[]={0,1,0};
int line3[]={0,0,1};
//定义整型指针数组并初始化
int *pLine[3]={line1,line2,line3};

cout<<“Matrix test:”<<endl;
for (int i=0;i<3;i++)
{
for (int j=0;j<3;j++)
cout<<pLine[i][j]<<" ";
cout<<endl;
}
return 0;
}

//6_9.cpp二维数组举例
#include
using namespace std;
int main()
{
int array2[3][3]={{11,12,13},{21,22,23},{31,32,33}};
for (int i=0;i<3;i++)
{
for (int j=0;j<3;j++)
cout<<((array2+i)+j)<<" ";
cout<<endl;
}
return 0;
}
8、用指针作为函数参数
//6_10.cpp读入三个小数,将整数部分和小数部分分别输出
#include
using namespace std;
//将实数分为整数部分和小数部分,形参intPart、fracPart是指针
void splitFloat(float x,int *intPart,float *fracPart)
{
*intPart=static_cast(x);//取x的整数部分
*fracPart=x-*intPart;//取x的小数部分
}
int main()
{
cout<<“Enter 3 float point numbers:”<<endl;
for(int i=0;i<3;i++)
{
float x,f;
int n;
cin>>x;
splitFloat(x,&n,&f);
cout<<“Integer Part=”<<n<<“Fraction Part=”<<f<<endl;
}
return 0;
}
9、指针形函数
当一个函数的返回值是指针类型时,这个函数就是指针型函数。
一般定义形式:
数据类型 *函数名(参数名)
{
函数体
}
10、指向函数的指针
数据类型 (函数指针名)(形参表)
//6_11.cpp函数指针实例
#include
using namespace std;
void printStuff(float)
{
cout <<“this is the print stuff function.”<<endl;
}
void printMessage(float data)
{
cout<<“the data to be listed is”<<data<<endl;
}
void printFloat(float data)
{
cout <<“the data to be printed is”<<data<<endl;
}
const float PI=3.1415926f;
const float TWO_PI
2.0f;

int main()
{
void(*functionPointter)(float);
printStuff(PI);
functionPointer=printStuff;
functionPointter(PI);
functionPointer=printMessage;
functionPointer(TWO_PI);
functionPointer(13.0);
functionPointer=printFloat;
functionPointer(PI);
printFloat(PI);
return 0;
}

11、对象指针
声明对象指针的一般形式是:
类名 *对象指针名;
例如:Point *pointPtr; //声明Point类的对象指针变量PointPtr
Point pl; //声明Point类的对象pl
PointPtr=&pl; //将对象pl的地址赋给PointPtr,使PointPtr指向pl
就像通过对象名来访问对象的成员一样,使用对象指针一样可以方便的访问对象的成员,语法形式为:
对象指针->成员名

//6_12.cpp
#include
using namespace std;

class Point
{
public:
Point(int x = 0, int y = 0) :x(x), y(y) {}

int getX() const { return x; }
int getY() const { return y; }

private:
	int x, y;

};
int main()
{
Point a(4, 5);
Point *p2 = &a;
cout << p2->getX() << endl;
cout << a.getX() << endl;
return 0;
}

this指针:它用于指向正在被成员函数操作的对象
指向类的费静态成员的指针:
声明指针语句的一般形式为:
类型说明符 类名::*指针名;//声明指向数据成员的指针
类型说明符 (类名::*指针名)(参数表);//声明指向函数成员的指针
对于数据成员指针赋值的一般语法形式为:
指针名=&类名::数据成员名;
访问数据成员的时候,有以下两种形式:
对象名.*类成员指针名

	 对象指针名->*类成员指针名

//6_13.cpp(改造6_12.cpp,访问对象的公有成员函数的不同方式)
int main()
{
Point a(4,5);
Point *p2=&a;
int (Point::*funcPtr)() const=&Point::getx;
cout<<(a.*funcPtr)()<<endl; //使用成员函数指针和对象名访问成员函数
cout<<(p2->*funcPtr)()<<endl; //使用成员函数指针和对象指针访问成员函数
cout<<a.getX()<<endl; //使用对象名访问成员函数
cout<getX()<<endl; //使用对象指针访问成员函数

return 0;
}

6.3 动态内存分配
C++中动态分配技术可以保证程序在运行的过程中按照实际需要申请适量的内存,使用结束后还可以释放,这种程序运行过程中申请和
释放的存储单元也称为堆对象,申请和释放的过程一般称为建立和删除。其运算符分别是:new和delete。
使用方式:
new 数据类型 (初始化参数列表);
例如:
int* point;
point =new int(2);
delete用来删除由neww建立的对象,释放指针所指向的内存空间
格式:delete 指针名
6.4 用vector创建数组对象
C++标准库提供的被封装的动态数组----vector,而且具有各种类型
vector<元素类型>数组对象名(数组长度);
6.5 浅复制与深复制

6.6 字符串
字符串的存放与使用,在C++种两种方法:(1)使用字符数组(2)使用标准C++库中的string类
1、用字符数组存储和处理字符串
char str[8]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’,’\0’};
char str[8]=“program”;
char str[]=“program”;
以上三种形式等价。
尽管对用字符数组表示的字符串进行初始化还比较容易、只管,但进行许多其他字符串操作是却比较麻烦。执行很多字符串操作需要用到
cstring头文件中的字符串处理函数。例如复制字符串内容:strcpy函数,比较字符串大小的:strcmp函数;
将字符串连接起来的函数:strcat函数。对这些繁琐的操作,C++进行了封装,形成了string类。
2、string类
(1)构造函数的原型
string();//默认构函数,建立一个长度为0 的串
string(const char *s)//用指针s所指向的字符串常量初始化string类的对象
(2)string类的操作符
s+t //将串s和t连接成一个新串
s=t;//用t更新s
s+=t;//等价于s=s+t;
s==t;//判断s与t是否相等
s!=t;//判断s与t是否不等
s<t;//判断s是否小于t
s<=t;//判断s是否小于等于t
s>t;//判断s是否大于t
s>=t;//判断s是否大于等于t
s[i];//访问串中下标为i的字符

(3)常用函数功能简介
string类的成员函数有很多
string append(const char s);//将字符串s添加在本串尾
string assign(const char s);//复制,将s所指向的字符串赋值给本对象
int compare(const string &str)const;//比较本串与str中串的大小,本串《str串,返回负数
string &insert(unsigned int p0,const char
s);//将s所指向的字符串插入在本串中位置p0之前
string substr(unsigned int pos,unsigned int n)const;//取子串,取本串中位置pos开始的n个字符,构成新的string类对象作为返回值
string int find(const basic_string &str)const//查找并返回str在本串中第一次出现的位置
//6_23.cpp string类应用举例
#include
#include
using namespace std;
inline coid test(const char
title,bool value)
{
cout <<title<<“returns”<<(value?“true”:“false”)<<endl;
}
int main()
{
string s1=“DEF”;
cout<<“s1 id”<<s1<<endl;

string s2;
cout<<“Please enter s2:”;
cin>>s2;
cout<<“length of s2:”<<s2.length()<<endl;

test(“s1<+“ABC””,s1<=“ABC”);
test("“DEF”<=s1",“DEF”<=s1);

//链接运算符的测试
s2+=s1;
cout<<“s2=s2+s1:”<<s2<<endl;
cout<<“length of s2:”<<s2.length()<<endl;
return 0;
}

*/

/*
//6_12.cpp
#include
using namespace std;

class Point
{
public:
Point(int x = 0, int y = 0) :x(x), y(y) {}

int getX() const { return x; }
int getY() const { return y; }

private:
	int x, y;

};
int main()
{
Point a(4, 5);
Point *p2 = &a;
cout << p2->getX() << endl;
cout << a.getX() << endl;
return 0;
}
*/

/*
//6_11.cpp函数指针实例
#include
using namespace std;
void printStuff(float)
{
cout << “this is the print stuff function.” << endl;
}
void printMessage(float data)
{
cout << “the data to be listed is” << data << endl;
}
void printFloat(float data)
{
cout << “the data to be printed is” << data << endl;
}
const float PI = 3.1415926f;
const float TWO_PI=PI*2.0f;

int main()
{
void(*functionPointer)(float);
printStuff(PI);
functionPointer = printStuff;
functionPointer(PI);
functionPointer = printMessage;
functionPointer(TWO_PI);
functionPointer(13.0);
functionPointer = printFloat;
functionPointer(PI);
printFloat(PI);
return 0;
}

/
/

//6_1.cpp
#include
using namespace std;
int main()
{
int a[10], b[10];
for (int i = 0; i < 10; i++)
{
a[i] = i * 2 - 1;
b[10 - i - 1] = a[i];
}
for (int i = 0; i < 10; i++)
{
cout << “a[” << i << “]=” << a[i] << " ";
cout << “b[” << i << “]=” << b[i] << endl;
}
return 0;
}
*/

/*
//6_2.cpp 使用数组名作为函数参数
#include
using namespace std;
void rowSum(int a[][4], int nRow)
{
for (int i = 0; i < nRow; i++)
{
for (int j = 1; j < 4; j++)
a[i][0] += a[i][j];
}
}
int main()
{
int table[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
cout << table[i][j] << " ";
cout << endl;
}
rowSum(table, 3);
for (int i = 0; i < 3; i++)
cout << “Sum of row” << i << “is” << table[i][0] << endl;
return 0;
}

*/

/*
//6_5.cpp指针的定义、赋值与使用
#include
using namespace std;
int main()
{
int i;
int * ptr = &i;
i = 10;
cout << “i=” << i << endl;
cout << "对指针变量ptr使用指针运算符得到的是ptr存储的内存地址中的数值,则 ptr= " << *ptr << endl;
cout << “对变量i进行地址运算,&i得到i的地址为:” << &i << endl;
cout << “指针变量ptr存储的地址:” << ptr << endl;
return 0;
}
*/

/*
//6_6.cpp void类型的指针的使用
#include
using namespace std;
int main()
{
//void voidObject;
void *pv;
int i = 5;
pv = &i;
int pint = static_cast<int>(pv);
cout << “*pint=” << *pint << endl;
return 0;
}
*/

/*
//6_8.cpp利用指针数组输出单位矩阵
#include
using namespace std;
int main()
{
int line1[] = { 1,0,0 };//定义数组,矩阵的第一行
int line2[] = { 0,1,0 };
int line3[] = { 0,0,1 };
//定义整型指针数组并初始化
int *pLine[3] = { line1,line2,line3 };

cout << "Matrix test:" << endl;
for (int i = 0; i < 3; i++)
{
	for (int j = 0; j < 3; j++)
		cout << pLine[i][j] << "  ";
	cout << endl;
}
return 0;

}

*/

/*
//6_10.cpp读入三个小数,将整数部分和小数部分分别输出
#include
using namespace std;
//将实数分为整数部分和小数部分,形参intPart、fracPart是指针
void splitFloat(float x, int *intPart, float *fracPart)
{
*intPart = static_cast(x);//取x的整数部分
*fracPart = x - *intPart;//取x的小数部分
}
int main()
{
cout << “Enter 3 float point numbers:” << endl;
for (int i = 0; i < 3; i++)
{
float x, f;
int n;
cin >> x;
splitFloat(x, &n, &f);
cout << “Integer Part=” << n << “Fraction Part=” << f << endl;
}
return 0;
}

*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值