C++程序设计 第六章 数组、指针与字符串

用指针访问数组元素

定义指向数组元素的指针:

int a[10],*pa;
pa=&a[0] ; 或者 pa=a;
a[i],*(p+i),*(a+i),pa[i] 四者等效

指针数组

一种数组,其元素全部是指针

#include<studio>
using namespace std;
int main() {
	int line1[] = { 1, 0, 0 };	//矩阵的第一行
	int line2[] = { 0, 1, 0 };	//矩阵的第二行
	int line3[] = { 0, 0, 1 };	//矩阵的第三行
	
	//定义整型指针数组并初始化
	//line1,line2和line3为数组名,即为地址,所以用来初始化指针
	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;
}

指针与函数

以指针作为函数参数

原因:
1.需要实现数据的双向传递
2.传递一组数据时,只传递指针效率较高

#include <iostream>
using namespace std;
void splitFloat(float x, int *intPart, float *fracPart) {
   *intPart = static_cast<int>(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;
}

指向常量的指针做形参,避免调用形参的时候变动实参数据

void print(const int *p, int n) {
  cout << "{ " << *p;
  for (int i = 1; i < n; i++)
        cout << ", " << *(p+i);
  cout << " }" << endl;
}

函数指针

指向函数的指针变量,本质上是一个指针,主要用作调用函数和作为函数的参数

int (*func)(int x);

注意,不要将非静态局部地址用作指针类函数的返回值,即别使用指针类函数中定义的局部变量的地址作为该函数的返回值,而应该使用全局函数或主函数中的变量的地址作为指针函数的返回值,或者返回动态内存分配空间new新建的地址

指针函数

本质上是一个函数,其实就是返回值是指针的函数

int* func(int x,int y);
储存类型 数据类型 (*函数名)(函数参数列表)
int compute(int a,int b,int(*fun)(int,int)){
	return fun(a,b);
}
//调用时
compute(x,y,&max);//max为子函数

对象指针

Point *ptr;
ptr->getX() 等价于 (*ptr).getX()

this指针
当通过一个对象调用成员函数时,系统首先将该对象的地址赋值给this指针
例如

Point类中getX函数中的语句:
return x ;
相当于 
return this->x;

动态内存分配(对象数组)

  1. 不使用new定义数组,数组大小多少就构造多少次析构多少次,主函数return时自动调用析构函数
class A {
	public:
	    A() { cout << "A()" << endl; }
	    ~A() { cout << "~A()" << endl; }
};

int main()
{    
    A a[3];//定义了对象数组
    return 0;
}

输出

A()
A()
A()
~A()
~A()
~A()
  1. 使用new分配数组,需要程序要主动执行delete才会调用析构函数
class A {
	public:
	    A() { cout << "A()" << endl; }
	    ~A() { cout << "~A()" << endl; }
};

int main()
{
    A *p=new A[3];
    delete []p;
    return 0;
}

结果

A()
A()
A()
~A()
~A()
~A()

5.vector对象

vector<元素类型>数组对象名(数组长度)
vector<int> arr(5)
int main(){
std::vector<int> v={1,2,3};
for(auto i=v.begin();i!=v.end();i++)
	std::cout<<*i<<std::endl;

for(auto e:v)
	std::cout<<e<<std::endl;
}

深层复制与浅层复制

当对象成员数据中有指针存在时,简单的复制如Point b(a)会把指针地址一起复制过去,所以必须自己定义新的复制构造函数,如下:

ArrayOfPoints::ArrayOfPoints(const ArrayOfPoints& v){
size=v.size;
points=new Points[size];//开辟新的内存空间
for(i=0;i<size;i++)
	points[i]=v.points[i];
}

在深层复制中,在复制构造函数中必须为新的对象的指针类数据成员使用new来开辟新的内存空间
移动构造函数:将即将消亡的对象的数据复制给另一个对象,可以直接复制指针对象

//复制构造函数:需要开辟新的内存空间来对指针进行复制
IntNum(const IntNum &n):xtpr(new int(*n.xtpr)){
	}

//移动构造函数:可以直接把指针赋值
IntNum(const IntNum &&n):xtpr(n.xtpr){ //&& 为右值引用
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值