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/C++】数组名与指针的关系;数组名取地址;数组名的解引用与取地址; -> 正文阅读

[C++知识库]【踩坑记录】【C/C++】数组名与指针的关系;数组名取地址;数组名的解引用与取地址;

前序知识

  1. 获取变量类型的语句是:typeid(variable).name()
  2. sizeof 是个关键字,在编译阶段起作用。
  3. sizeof 数组名,得到的是数组的字节大小。

指针与数组名的区别

  • C专家编程 中有讲到,
  • 数组和指针在编译器处理时是不同的,在运行时的表示形式也是不一样的,并可能产生不同的代码。对编译器而言,一个数组就是一个地址,而一个指针就是一个地址的地址。
  • 数组名是不可修改的左值,不能直接对其赋值(定义时除外)。但可以用memcpy,strcpy等来进行间接“赋值”。
  • 讲到三个规定
  1. “表达式中的数组名被编译器当作一个指向该数组第一个元素的指针。”
  2. "下标总是与指针的偏移量相同。
  3. 在函数参数的声明中,数组名被编译器当作指向该数组的第一个元素的指针。”(作为形参,数组名退化为指针)
  • 讲到三个例外
  1. 数组作为sizeof()的操作数,显然此时需要的是整个数组的大小,而不是所指向第一个元素的大小
  2. 使用&操作符取数组的地址
  3. 数组是一字符串常量初始化值

验证

int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
int arr2[3] = { 2,5,6 };
int(*p)[3] = &arr2;

cout << "(arr)		\t" << (arr) << " \t" << sizeof(arr) << "\t" << typeid(arr).name() << endl;
cout << "(arr + 1)  \t" << (arr + 1) << " \t" << sizeof(arr + 1) << "\t" << typeid(arr + 1).name() << endl;
cout << "(*arr)		\t" << (*arr) << " \t" << sizeof(*arr) << "\t" << typeid(*arr).name() << endl;
cout << "(*arr + 1)	\t" << (*arr + 1) << " \t" << sizeof(*arr + 1) << "\t" << typeid(*arr + 1).name() << endl;
cout << "(*(arr + 1))\t" << (*(arr + 1)) << " \t" << sizeof(*(arr + 1)) << "\t" << typeid(*(arr + 1)).name() << endl;
cout << "(&arr)		\t" << (&arr) << " \t" << sizeof(&arr) << "\t" << typeid(&arr).name() << endl;
cout << "(&arr+1)	\t" << (&arr + 1) << " \t" << sizeof(&arr + 1) << "\t" << typeid(&arr + 1).name() << endl;

cout << "*******************************************************************" << endl;

cout << "(arr2)		\t" << (arr2) << " \t" << sizeof(arr2) << "\t" << typeid(arr2).name() << endl;
cout << "(&arr2)	\t" << (&arr2) << " \t" << sizeof(&arr2) << "\t" << typeid(&arr2).name() << endl;
cout << "(arr2+1)	\t" << (arr2 + 1) << " \t" << sizeof(arr2 + 1) << "\t" << typeid(arr2 + 1).name() << endl;
cout << "(*arr2)	\t" << (*arr2) << " \t" << sizeof(*arr2) << "\t" << typeid(*arr2).name() << endl;
cout << "(*arr2+1)	\t" << (*arr2 + 1) << " \t" << sizeof(*arr2 + 1) << "\t" << typeid(*arr2 + 1).name() << endl;
cout << "((*arr2 )+1)\t" << ((*arr2) + 1) << " \t" << sizeof((*arr2) + 1) << "\t" << typeid((*arr2) + 1).name() << endl;
cout << "(p)	    \t" << (p) << " \t" << sizeof(p) << "\t" << typeid(p).name() << endl;
  • X86下结果
(arr)                   0117F834        36      int [3][3]
(arr + 1)       		0117F840        4       int (*)[3]
(*arr)                  0117F834        12      int [3]
(*arr + 1)              0117F838        4       int *
(*(arr + 1))    		0117F840        12      int [3]
(&arr)                  0117F834        4       int (*)[3][3]
(&arr+1)                0117F858        4       int (*)[3][3]
**********************************************
(arr2)                  0117F820        12      int [3]
(&arr2)         		0117F820        4       int (*)[3]
(arr2+1)                0117F824        4       int *
(*arr2)         		2       		4       int
(*arr2+1)               3       		4       int
((*arr2 )+1)    		3       		4       int
(p)             		0117F820        4       int (*)[3]

一维数组

  • int arr2[3] = { 1,2,3 };
namemeaningtype
(arr2)数组名:指向第一行的指针(二维指针常量)int [3]
(&arr2)一维数组的指针;(数组指针)int (*)[3]
(arr2+1)数组指针+偏移;(指针)int *
(*arr2)数组名解引用;(值)int
(*arr2+1)数组名解引用+偏移;(值)(和下面一致;先解引用int
((*arr2 )+1数组名解引用+偏移;(值)int

二维数组

  • arr[i][j]
namemeaningtype
(arr)数组名:指向第一行的指针;(二维指针常量)int [3][3]
(arr + 1)数组名+偏移;(指向一维数组的指针)int (*)[3]
(*arr)数组名解引用;(一维指针常量)int [3]
(*arr + 1)数组名解引用+偏移;(指针)int *
(*(arr + 1))数组名+偏移 +解引用;一维指针常量int [3]
(&arr)数组名取地址;(指向二维数组的指针)int (*)[3][3]
(&arr+1)数组名+偏移+取地址;(指向二维数组的指针)int (*)[3][3]
  • tips:

若要快速得到一个二维数组最后一个元素的值可以这样

int *ptr = (*int)(&arr + 1);
cout << *(ptr - 1) << endl;
  • arr只是arr[0]的地址,arr+1就是arr[1]的地址了.
  • &arr是整个arr[10]的首地址,是以整个数组为角度来看,虽然它与arr[0]的值相同,但是&arr+1就已经增加了10个int类型的字节的长度了.
    在这里插入图片描述
  • 即,对数组名取地址,得到的是数组名所指元素的地址。和指针不同;(编译器特性)

参考

【C专家编程】

https://blog.csdn.net/hmxz2nn/article/details/80157461

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-21 15:10:21  更:2021-08-21 15:10:38 
 
开发: 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/19 21:28:32-

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