6_数组_指针_字符串

数组-指针-字符串

数组

数组的定义与初始化

  • 类型符 数组名[常量表达式];
  • 数组必须先定义,再使用
  • 数组名字是数组首元素的内存地址,是一个常量,不能被赋值
  • 数组可以作为函数的参数:形参会影响实参,一般数组长度也要作为参数传入
  • 对象数组
int a[10];  //定义整形一维数组
int a[2][5];  //定义整形二维数组
Point a[2];  //定义Point类对象数组

int a[10]={0,1,2,3};  //初始化
int a[]={0,1,2};    //编译器根据初始化的元素确定数组大小
Point a[2] = {Point(1,2), Point(3,4)};  //初始化

int a[2][2]={{1},{3,4}};  //二维初始化

//作为函数的参数 
#include <iostream>
using namespace std;

void add(int a[], int b[], int len_a, int len_b){
    for(int i=0;i<len_a;i++){
        a[i] = a[i] + b[i];
    }
}

int main(){
    int a[3] = {1,2,3};
    int b[3] = {4,5,6};
    add(a, b, 3, 3);
    for(int i=0; i<3;i++){
        cout << a[i] << endl;
    }
    return 0;
}

基于范围的for循环

int main(){
    int a[3] = {1,2,3};
    int *p;
    for(p = a; p < a + sizeof(a)/sizeof(int);p++){
        cout << *p << endl;
    }
    return 0;
}

int main(){
    int a[3] = {1,2,3};
    for(int & e:a){  //遍历容器,需要C++11标准
        cout << e << endl;
    }
    return 0;
}

vector

vector<int> arr(5);  //建立大小为5的int数组
arr.size();   //返回元素个数
arr[0];

add(vector<int> &v1, vector<int> &v2);

指针

指针的定义

  • 本质为内存地址,间接访问存储单元
  • 指针运算符 * 和 地址运算符 &
  • *指向常量的指针 const int p = &a 不可以通过指针改变所指的对象
  • 指针类型的常量 int * const p2 = &a p2的值不能更改,p2不能再指向别的对象
  • 指针运算
int i=0, j=1;
int *p = &i;  //指针p指向i
int *p; p = &i; //指针p指向i
int *p = nullptr; //定义空指针,int *p = 0
int void *p;   //可以被赋予任何类型对象的地址;只能用于存放地址,不能通过它访问对象的值(可以先强制转换再访问)

*p = 3;  //通过指针间接更改i

int *p2 = &b;
p = p2;   //指针赋值

p = p + 1;  //指针向后方移动一个数据的大小,即指向下一个数据

指针与数组

int a[10];
int *p;
pa=&a[0]; pa = a;  //指针指向数组
//*p=a[0]    *(pa+1)=a[1]

指针数组

  • 数组的元素为指针类型
int line1[] = {1,0,0};
int line2[] = {0,1,0};
int line3[] = {0,0,1};
int *p[3] = {line1, line2, line3}

指针与函数

  • 指针作为函数的参数:双向传递, 数组太大
  • 指针类型的函数 int* add(int, int)

指向函数的指针

存储类型 数据类型(*函数指针名)(形参列表)

典型用途:函数的回调(将函数指针作为函数的参数传递)

#include <iostream>
#include "point.h" 
using namespace std;

int compute(int a, int b, int(*func)(int, int))
{return func(a,b);}

int max(int a, int b)
{return ((a > b) ? a: b);}

int min(int a, int b)
{return ((a < b) ? a: b);}

int sum(int a, int b)
{return a+b;}

int main(){
	int a=1, b=2;
	cout << compute(a, b, &min) << endl;
	cout << compute(a, b, &max) << endl;
	cout << compute(a, b, &sum) << endl;
	return 0;
}

动态分配

动态内存分配

int *p = new int[10];
delete[] p;

int *p = new Point(1,2);
delete p;

字符串

C风格字符串

char str[8] = "hello";   //以\0为结尾
char str[] = "hello";

string

#include <string>
string s = "hello";
s[0] = 'H';

s1+s2; // 字符串拼接

s.length()

对象指针

this指针

通过一个对象调用成员函数时,系统会将该对象的地址赋值给this指针,然后调用成员函数时隐含的使用了this指针

//定义
Point a(5, 10);
Point *ptr = &a;
//访问对象成员
ptr->getX();  //等价于(*ptr).getX();
//this指针
int Point::getX()
{
    return x;  //等价于return this->x;
}

智能指针

unique_ptr :不允许多个指针共享资源,可以使用move函数转移指针

shared_ptr:多个指针共享资源

weak_ptr:可以复制shared_ptr,但是其构造和释放对资源不产生影响

对象的复制与移动

深拷贝与浅拷贝

浅拷贝:对象成员的一一复制,当对象中含有指针时,会导致多个指针指向同一个资源

深拷贝:指针不指向同一份资源,会新建另外一份资源,然后将资源的值一一复制过来

移动构造函数

不进行复制,而是转移(C++11)

可以对临时对象(即将消亡)的资源直接移动,避免了多余的复制操作

#include<iostream>
using namespace std;

class IntNum {
	public:
		IntNum(int x = 0) : xptr(new int(x)){ //构造函数
		cout << "Calling constructor..." << endl;
	}

	IntNum(const IntNum & n) : xptr(new int(*n.xptr)){//复制构造函数
		cout << "Calling copy constructor..." << endl;
	};

	 IntNum(IntNum && n): xptr( n.xptr){ //移动构造函数
 		n.xptr = nullptr;
		cout << "Calling move constructor..." << endl;
	}

	~IntNum(){ //析构函数
		delete xptr;
		cout << "Destructing..." << endl;
	}

	int getInt() { return *xptr; }

	private:
	int *xptr;
};

IntNum getNum() {
	IntNum a;
	return a;
}

int main() {
	cout << getNum().getInt() << endl;
	return 0;
}

posted @ 2020-07-16 19:11  happy_fan  阅读(164)  评论(0编辑  收藏  举报