IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 数组与指针 -> 正文阅读

[C++知识库]数组与指针

与指针相关的运算符

地址运算符注解示例
&后跟一个变量名时,&给出该变量的地址&address表示address的地址
*后跟一个指针名或地址时,*给出存储在指针指向地址上的值*num表示num的值

简单变量把值作为基本量,把地址作为通过&运算符的主要用途。更重要的是通过&、和指针可以操纵地址和地址上的内容

指针和数组

数组和指针的关系十分密切,可以使用指针标识数组的元素和获得元素的值。从本质上看,同一个对象有两种表示法。C语言标准在描述数组表示法时的确借助了指针。

ar[n]的意思是 *(ar+n)
可以认为 *(ar+n)的意思是 ”到内存的ar位置 然后移动n个单位“

数组名是数组首元素的地址

/*
本质上,同一种对象有两种表现形式
指针表示法 数组表示法
*/
int main()
{
    int arr[2]={1,2};
    printf("%p %p",&arr[2],arr+2); //取地址
    printf("%d %d",*(arr+2),arr[2]); //取值
}
sum+=*index++;
一元运算符 * 和++的优先级相同,但结合律是从右往左的,所以index++先求值,然后才是*index,
也就是指针index先递增后指向,使用后缀形式(index++)意味着先把指针指向位置上的值加到sum上,然后再递增指针。
如果使用*++index,顺序反过来,先递增指针再使用指针指向位置上的值
如果使用(*index)++,则先获取指针位置上的值再递增该值

const修饰

int arr[4]={1,2,3,4};

**********************第一种情况**********************
//不允许通过p修改指向的值,但可以通过数组修改值,可以让p指向其他值,可以修改p的地址
    const int *p=arr;	//p指向数组的首元素
    *arr=10; 			//左值指定为const对象 只读【报错】

**********************第二种情况**********************
void test_const(const int *p) //指向const的指针通常用于函数形参中,表明该函数不会使用指针改变数据
    
**********************第三种情况**********************
int * const p=arr; //声明并初始化一个不能指向别处的指针[不能修改地址,可以修改地址指向的值]

**********************第四种情况**********************
const int *const p=arr; //声明并初始化一个不能修改地址 也不能修改地址指向值 的指针变量

指针与多维数组

int arr[2][3] = { {1,2,3},{4,5,6} }; //声明一个2行3列的二维数组
  • 因为数组名arr是数组首元素的地址,所以arr的值和&arr[0]的值一样。而arr本身是一个内含两个整数的数组,所以arr[0]和它首元素(一个整数)的地址(&arr[0][0]的值)相同
    arr[0]是一个占有一个int大小对象的地址,而arr是一个占有两个int大小对象的地址。因为这个整数和内含两个整数的数组都开始于同一个地址,所以arr和arr[0]的值相同
  • 给指针和地址+1,其值会增加对应类型大小的数值。arr和arr[0]不同,因为arr指向的对象占用了两个int大小,而arr[0]指向的对象只占一个int大小。因此arr+1和arr[0]+1的值不同
  • 解引用一个指针(使用*运算符)或在数组名后使用带下标[]运算符,得到引用对象代表的值。因为arr[0]是数组首元素(arr[0][0])的地址,所以 *(arr[0])表示存储在arr[0][0]上的值(1个int类型的值)

在这里插入图片描述

int main()
{
	int arr[4][2] = { {2,4},{6,8},{1,3},{5,7} };
	printf("arr=%p, arr+1=%p \n", arr, arr + 1);
	printf("arr[0]=%p, arr[0]+1=%p\n", arr[0], arr[0] + 1);
	printf("*arr=%p, *arr+1=%p\n", *arr, *arr + 1);
	printf("arr[0][0]=%d\n", arr[0][0]);
	printf("**arr=%d\n", **arr);
	printf("arr[2][1]=%d\n", arr[2][1]);
	printf("*(*(arr+2)+1)=%d", *(*(arr+2)+1));
	return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WgLn9aU9-1636958440304)(C:\Users\Meaauf\Desktop\屏幕截图 2021-11-15 091946.jpg)]

理解表达式的思路:

arr二维数组首元素地址(每个元素都包含两个int类型的一维数组)
arr+2二维数组的第3个元素的地址【一维数组】
*(arr+2)二维数组的第3个元素【一维数组】的首元素【1个int类型】地址
*(arr+2)+1二维数组的第3个元素【一维数组】的第2个元素【1个int类型】地址
* (*(arr+2)+1)二维数组的第3个元素【一维数组】的第2个元素【1个int类型】的值 ==arr[2][1]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TkAPezum-1636958440305)(C:\Users\Meaauf\AppData\Roaming\Typora\typora-user-images\image-20211115094631412.png)]

个人理解:对于多维数组而言,*运算符只有精确到1位int类型的时候,才能返回准确的int值。

声明多维数组的的指针

int (*p)[2]; //指向一个内含两个int类型值的数字
int *p[2];   //声明一个内含两个指针元素的数组,每个元素指向int的指针
/*
因为[]的优先级比*高,所以语句2 p先与[]结合,成为一个内含2个元素的数组;再与*结合,表示内含两个指针;最后int表示类型
*/

实例

int main()
{
	int arr[4][2] = { {2,4},{6,8},{1,3},{5,7} };
	int(*p)[2];
	p = arr;
	printf("p=%p, p+1=%p\n", p, p + 1);
	printf("p[0]=%p, p[0]+1=%p\n", p[0], p[0] + 1);
	printf("p[0][0]=%d\n", p[0][0]);
	printf("*p[0]=%d\n", *p[0]);
	printf("**p=%d\n", **p);
	printf("p[2][1]=%d\n", p[2][1]);
	printf("*(*p+2)+1=%d", *(*(p + 2) + 1));
	return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S7kblc6o-1636958440307)(C:\Users\Meaauf\Desktop\屏幕截图 2021-11-15 104553.jpg)]

p虽然是一个指针,不是数组名,但是也可以使用数组表示法(p[2][1])。可以使用数组表示法或指针表示法来表示一个数组元素,既可以使用数组名也可以使用指针名

arr[n][m]==*(*(arr+n)+m)
p[n][m]==*(*(p+n)+m)

指针的兼容性

指针之间的赋值比数值之间的赋值要严格,标准规定了非const指针更改const数据是未定义的

int main()
{
	const int** p;
	int* p1;
	const int a = 13;
	p = &p1;	//导致const限定符失效
	*p = &a;	//两种都为const,导致p1指向1
	printf("%d\n", **p);
	*p1 = 10;	//a值被改变
	printf("%d", a); //最终导致结果为10
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-16 18:39:12  更:2021-11-16 18:39:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:24:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码