指针笔记

学习笔记:

指针(一)

一、指针的概念

1、每个数据类型变量定义后在计算机中都会随机给予一定的内存段,计算机会有固定的内存编号,一般叫做首地址

2、指针就是将自身定义成可以存首地址变量

3、也就是说指针也是一种数据类型,所以指针也有自己的内存编号,而它存储的是地址(内存编号)

要素:

1 指针本身的类型 除去指针名,剩下的就是指针本身的类型

2 指针指向的类型 除去指针名和一个*,剩下的就是指针指向的类型

3 指针本身的内存 用来存储指向内容的地址(指针里面,只存编号)(四个字节)

4 指针指向的内存 可以是各种类型

二 指针的定义

1 运算符

* : 定义时,表示定义的是一个指针——其他时候表示解析引用(取内容)(解引用)

& : 取首地址符

2 定义

#include <iostream>

int main()
{
	/* 定义变量 */
	// 类型 变量名;
	int num = 10;

	/* 指针也是一种数据类型 */
	// 指针类型 指针名;
	// 指针指向的类型* 指针名;

	// ==>	1 除去指针名,剩下的就是指针本身的类型
	//		2 除去指针名和一个*,剩下的就是指针指向的类型
	
	// 定义了一个int*类型的指针 叫做p
	// p 这个指针,本身的类型是:int*
	// p 这个指针,指向的类型是:int
	int* p;


	return 0;
}

三 指针的内存

1、所有的指针,不论类型,在内存中都占4个字节的内存.

	char* pch;
	short* psh;
	int* pn;
	float* pf;
	double* pd;

	printf("%d\n", sizeof(pch));
	printf("%d\n", sizeof(psh));
	printf("%d\n", sizeof(pn));
	printf("%d\n", sizeof(pf));
	printf("%d\n", sizeof(pd));

四 指针的初始化和赋值

1 用对应类型变量的地址

	int num = 10;
	int* p = &num;	// 初始化

	short sh = 20;
	short* p1;
	p1 = &sh;		// 赋值

2 用相同类型的指针

	int num = 10;
	int* p = &num;	// 初始化
	int* p1;
	p1 = p;

3 直接用地址

	int* p = (int*)0X36;

4 用数组名

	// 数组名就是数组的首地址!!!
	int arr[5] = { 1, 2, 3, 4, 5 };
	int* p = arr;

5 字符串

	char arr[10] = "abcd";
	char* p = arr;

	char* p1 = "abcd";

	printf("%X\n", p);
	printf("%s\n", p);

	printf("%X\n", p1);
	printf("%s\n", p1);
	cout << p1 << endl;
// ==》 char*类型的指针,可以用来直接输出整个字符串,直到遇见'\0'

6 置空

有时候,指针定义了,还没有指向.

或者是,指针用完了,没有指向了.

此时不知道应该指向哪里.

此时的指针,很危险.(野指针)

所以,这些情况下的指针,我们给他们一个固定的指向.

指向0地址(NULL)(nullptr)((int*)0X0)

	int* p1 = NULL;
	int* p2 = nullptr;
	int* p3 = (int*)0X0;
	char* p4 = (char*)0X0;//不同的类型用不同的类型指针来强转

7 多级指针

1、概念:指针本身也是个数据类型,也会有地址,所以可以用多级指针指向指针首地址

#include <iostream>
using namespace std;
#include <stdio.h>

int main()
{
	int num = 10;
	cout << "num = " << num << endl;
	cout << "&num = " << &num << endl << endl;

	int* pnum = &num;
	cout << "pnum = " << pnum << endl;
	cout << "&pnum = " << &pnum << endl;
	cout << "*pnum = " << *pnum << endl << endl;

	int** ppnum = &pnum;
	cout << "ppnum = " << ppnum << endl;
	cout << "&ppnum = " << &ppnum << endl;
	cout << "*ppnum = " << *ppnum << endl;
	cout << "**ppnum = " << **ppnum << endl << endl;

	int*** pppnum = &ppnum;
	cout << "pppnum = " << pppnum << endl;
	cout << "&pppnum = " << &pppnum << endl;
	cout << "*pppnum = " << *pppnum << endl;
	cout << "**pppnum = " << **pppnum << endl;
	cout << "***pppnum = " << ***pppnum << endl << endl;

	

	return 0;
}

	short sh = 10;
	
	short* psh1 = &sh;
	short* psh2 = psh1;

	short** ppsh1 = &psh2;
	short** ppsh2 = ppsh1;

	short*** pppsh = &ppsh2;

	***pppsh = 9;

	cout << "sh = " << sh << endl;		// 9 

五 指针的加减法

核心:指针本身的值(指向)有没有变化?

指针偏移

不改变指针的指向

1 指针可以加上或者减去一个整数

2 指针加上或减去一个整数后,实际上是进行了偏移,偏移的范围是加上或减去的整数个单位

单位: 指针指向的类型在内存所占的字节数

偏移: 指针指向不变,但是根据偏移量取内容

六 指针自增自减

自增自减,会改变指向

++: 表示指针向后移动一个单位

--: 表示指针向前移动一个单位

单位: 指针指向的类型在内存所占的字节数

七 指针与数组

通过指针遍历一维数组

#include <iostream>
using namespace std;
#include <stdio.h>

int main()
{
	int arr[5] = { 1, 2, 3, 4, 5 };

	for (size_t i = 0; i < 5; i++)
	{
		cout << arr[i] << endl;
	}
	
	int* parr = arr;
	for (size_t i = 0; i < 5; i++)
	{
		cout << parr[i] << endl;		// 下标(数组)
	}

	// parr 和 arr 是一样的
	// 但是arr是一个常量
		
	cout << *(parr + 0)<< endl;			// 1
	cout << parr[0] << endl;			// 1
	cout << *(parr + 1) << endl;		// 2
	cout << parr[1] << endl;			// 1
	cout << *(parr + 2) << endl;		// 3
	cout << *(parr + 3) << endl;		// 4

	// *(parr + 0)	 parr[0] 
	// *(parr + 1)	 parr[1] 
	// *(p + n)  <==> p[n]


	return 0;
}

指针与二维数组?

	int arr[3][4] = {
		{ 1, 2, 3 },
		{ 4, 5, 6 },
		{ 7, 8, 9 }
	};

	// int* p = &(arr[0][0]);		// *(p + n)  <==> p[n]
	// arr[0][0]   ==>  *(arr[0] + 0)	==>   *(*(arr+0) + 0)	==> *(*(arr))
	// *(arr)  ==>  arr[0]

	int* p = arr[0];

	
	for (int i = 0; i < 12; i++)
	{
		cout << p[i] << endl;
	}

为什么会有0?
因为在数组初始化时只给到三列,第四列就默认赋值为0;

存储模式

1 小端模式(VS)

存储: 低字节存数据的低位

读取: 从高向低读取(逻辑习惯)

2 大端模式

存储: 低字节存数据的高位

读取: 从低向高读取(阅读习惯)

作业:

int num = 0XABCD1234;
int* pn = &num;
short* p = (short*)pn;
printf("%X\n",*(p+1));

要求:画图

posted @ 2020-11-26 15:41  onedust  阅读(155)  评论(0)    收藏  举报