Bootstrap

【C++】指针学习 代码记录

#include<iostream>
//字符串
#include<string>
//格式化输出
#include<iomanip>
//获取类型
#include<typeinfo>
//begin和end函数
#include<iterator>

using namespace std;

class point {
private:
	int number;
	string name;
public:
	point(int num, string nam) :number(num), name(nam) {  }
	void show() const;
	void test() const;
};

void point::show() const{
	cout << "number:" << number << endl;
	cout << "name:" << name << endl;
}

//当局部作用域中声明了与类成员同名的变量,对该标识符的直接引用代表局部中声明的,使用this指针可以访问类成员中的同名变量
void point::test() const {
	int number = 10;
	cout << "number:" << number << endl;
	cout << "this->number:" << this->number << endl;
}

//前向引用声明
class Fred;
class Barney {
	//Fred x;   //错误
	Fred* x;   //正确
};
class Fred {
	Barney y;
};


//将实数分成整数部分和小数部分
void split(float x, int *intpart, float *fracpart) {
	*intpart = static_cast<int>(x);
	*fracpart = x - *intpart;
}

double doubleint(int a) {
	cout << "This is double_int " << endl;
	return static_cast<double>(a);
}

int intdouble(double a) {
	cout << "This is int_double " << endl;
	return static_cast<int>(a);
}


int main() {
	//数组名实际上是一个不能被赋值的指针(指针常量)
	int a[10];
	int* ptr_a = a;
	int i;
	//引号在右边是取地址赋值,在左边表示引用
	int& i2 = i;
	int* ptr_i = &i;
	i = 10;
	cout << "i = " << i << endl;
	cout << "*ptr_i = " << *ptr_i << endl;
	//指向常量的指针(不能通过指针来改变对象的值,但是指针本身可以改变,可以指向另外的对象)
	int c = 10;
	const int* p1 = &c;
	int b = 20;
	p1 = &b;
	//*p1 = 10;		编译错误
	//可以确保指针指向的变量值不通过指针发生改变
	//指针类型的常量(指针指向不能改变)
	int* const p3 = &c;
	//p3 = &b;		编译错误
	//void类型指针(可以储存任何类型的对象地址)
	//注:没有viod类型的变量
	void* pv;
	int j = 5;
	pv = &j;
	cout << "The type of pv : " << typeid(pv).name() << endl;
	// cout << "*pv = " << *pv;		报错
	//显示类型转换后才能间接访问
	int* pint = static_cast<int*>(pv);
	cout << "The type of pint : " << typeid(pint).name() << endl;
	cout << "*pint = " << *pint << endl;
	//空指针(避免指向不确定地址)
	int* p;
	p = 0; //表示将p设为空指针,不指向任何地址
	int* p0 = NULL; //也代表空指针
	//用指针处理数组元素
	for (int i = 0; i < 10; i++) {
		a[i] = i;
	}
	//使用数组名和指针运算
	for (int i = 0; i < 10; i++) {
		cout << *(a + i) << " ";
	}
	cout << endl;
	//使用指针变量
	for (int* p = a; p < (a + 10); p++) {
		cout << *p << " ";
	}
	//标准库函数begin和end获取首位元素地址
	int* beg = begin(a);
	int* last = end(a);
	while (beg != last) {
		cout << *beg << " ";
		beg++;
	}
	cout << endl;
	//指针数组(本质是一个数组,其中每个数组元素都是一个指针)
	//利用指针数组输出单位矩阵.cpp
	int line1[] = { 1,0,0 };
	int line2[] = { 0,1,0 };
	int line3[] = { 0,0,1 };
	int* pLine[3] = { line1,line2,line3 };		//定义整型指针数组并为其初始化
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			cout << pLine[i][j] << " ";
		}
		cout << endl;
	}
	cout << "1---------" << endl;
	//把二元数组当作指针数组来访问
	int array[3][3];
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			array[i][j] = i + 2 + j;
		}
	}
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			cout << *((*array + i) + j) << " ";
		}
		cout << endl;
	}
	cout << "2---------" << endl;
	//数组指针(本质是指针,指向一个数组)
	int arr[2] = { 10,20 };
	int(*arrptr)[2] = &arr;
	cout << *arrptr << endl;	//输出数组名地址
	for (int i = 0; i < 2; i++) {
		cout << (*arrptr)[i] << " ";
	}
	cout << endl;
	//用指针作为函数参数
	//使用引用作为形参传递也能做到相同作用
	cout << "3---------" << endl;
	float split_x, fracpart;
	int intpart;
	split_x = 3.1425926;
	split(split_x, &intpart, &fracpart);
	cout << "X : " << split_x << " intpart:" << intpart << " fracpart:" << fracpart << endl;
	//指向函数的指针
	// 函数名表示函数的代码在内存中的起始地址,调用函数的实质就是函数代码首地址,函数指针是来存放函数代码首地址的变量,在程序中可以像使用函数名一样使用指向函数的指针来调用函数
	//声明了一个有double形参,返回类型为Int的指针
	typedef double (*Double_Int)(int);
	//使用yype可以很方便的为复杂类型起别名,把要声明的类型别名放到声明这种类型的变量时书写变量名的位置即可
	//声明这一类型的变量
	Double_Int DoubleInt;
	//直接声明
	int (*IntDouble)(double);
	//初始化即直接赋值
	DoubleInt = &doubleint;   //函数返回值与传参类型必须相同(否则编译错误)
	IntDouble = intdouble;    //可以取地址也可以不取
	double dint;
	dint = doubleint(3);   //函数调用
	dint = DoubleInt(5);   //指针调用
	cout << "4---------" << endl;
	//对象指针
	point* pointptr;
	point point1(1,"zhang");
	pointptr = &point1;
	pointptr->show();	//使用指针访问对象成员
	point1.show();	   //使用对象自己访问
	cout << "5---------" << endl;
	//this指针
	point1.test();
	cout << "6---------" << endl;
	//指向类的非静态成员的指针
	int point::* numberptr;		//声明指向数据成员的指针
	void (point:: * showptr)() const;	  //声明指向函数成员的指针
	//赋值
	// numberptr = &point::number;  //不能在外部访问私有成员
	showptr = &point::show;
	//通过对象使用指针访问类的非静态成员
	//point1.*numberptr;
	//pointptr->*numberptr;
	(point1.*showptr)();  //必须有括号
	//通过对象指针访问
	(pointptr->*showptr)();
	cout << "7---------" << endl;
	//指向类的静态成员函数的指针
	//6_14.cpp
	return 0;
}
//输出
i = 10
*ptr_i = 10
The type of pv : void * __ptr64
The type of pint : int * __ptr64
*pint = 5
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
1 0 0
0 1 0
0 0 1
1---------
2 3 4
3 4 3
4 3 4
2---------
0000009C53EFF0E8
10 20
3---------
X : 3.14259 intpart:3 fracpart:0.142593
This is double_int
This is double_int
4---------
number:1
name:zhang
number:1
name:zhang
5---------
number:10
this->number:1
6---------
number:1
name:zhang
number:1
name:zhang
7---------
;