广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >详解C++数组和数组名问题(指针、解引用)
  • 759
分享到

详解C++数组和数组名问题(指针、解引用)

2024-04-02 19:04:59 759人浏览 八月长安
摘要

目录一、指针 1.1 指针变量和普通变量的区别1.2 为什么需要指针1.3 指针使用三部曲二、整形、浮点型数组2.1 数组名其实是特殊的指针2.2 理解复杂的数组的声明2.

一、指针

 1.1 指针变量和普通变量的区别

指针:指针的实质就是个变量,它跟普通变量没有任何本质区别。指针完整的应该叫指针变量,简称为指针。 是指向的意思。指针本身是一个对象,同时指针无需在定义的时候赋值

1.2 为什么需要指针

指针的出现是为了实现间接访问。在汇编中都有间接访问,其实就是CPU的寻址方式中的间接上。

间接访问(CPU的间接寻 址)是CPU设计时决定的,这个决定了汇编语言必须能够实现问接寻又决定了汇编之上的C语言也必须实现简介寻址。

1.3 指针使用三部曲

三部曲:定义指针变量、关联指针变量、解引用

(1)当我们int *p定义一个指针变量p时,因为p是局部变量,所以也道循C语言局部变量的一般规律(定义局部变量并且未初始化,则值是随机的),所以此时p变量中存储的是一个随机的数字。

(2)此时如果我们解引用p,则相当于我们访问了这个随机数字为地址的内存空间。那这个空间到底能不能访问不知道(也许行也许不行),所以如果直接定义指针变量未绑定有效地址就去解引用几平必死无疑。

(3)定义一个指针变量,不经绑定有效地址就去解引用,就好象拿一个上了镗的枪随意转了几圈然后开了枪。

(4)指针绑定的意义就在于让指针指向一个可以访问、应该访问的地方(就好象拿着枪瞄准且标的过程一样),指针的解引用是为了间接访问目标变量(就好象开枪是为了打中目标一样)


int val = 43;
int * p = &val;   // &在右值为取值符
cout << *p << endl;

//输出
43

二、整形、浮点型数组

 前言

  • 在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向该数组首元素的指针。
  • 所以,在大多数表达式中,使用数组名其实是在使用一个指向该数组首元素的指针。

2.1 数组名其实是特殊的指针


int main()
{
	int a[] = { 0,1,2,3,4 };
	printf("%x\n", a);
	printf("%x\n", &a);
	printf("%x\n", &a[0]);
}

在这里插入图片描述

  • 从局部变量表可以看出,数组a和指针p的构成是很相似的。它们实际存的都是一个地址,都会指向一个对象(或多个对象的第一个对象)。所以说数组名其实是种特殊的指针。
  • 为什么说是特殊呢?

一维数组


 int a[] = { 0,1,2,3,4 };
    int * p1 = a;
    int *p = &a[0];
    //指针p是 int * 的,而首元素是有地址的,所以取址,是允许的
    
	//int * p1 = &a;    //错误
	//理解:int (*p1)[5] = &a;  //正确
		

整理:

指针 类型
a int *
&a int (*) [5]

二维数组


int ia[3][4];
       int (*p)[4] = ia;      //ia 的类型就是 int(*)[4]
       int (*p)[3][4] = &ia;  //&ia的类型就是 int(*)[3][4]

整理:

指针 类型iaint (*) [4]&1aint (*) [3] [4]

2.2 理解复杂的数组的声明

上述提到数组名是指向一个数组的指针,因此解释一下一些复杂的数组声明。加深理解


 int * ptr[10];             //ptr是含有10个  整形指针  的数组
   int & ref[10]  =    //错误,不存在引用的数组
   int (*parray) [5] = &a;   //parray指向一个含有5个整数的数组
   
   
   int (&array)[5] = a;      //array引用一个含有5个整数的数组

   int * (&array) [10]  = ptrs;
   //array是数组的引用, 该数组是含有10个指针的数组

2.3 数组名a、数组名取地址&a、数组首元素地址&a[0]、指向数组首元素的指针*p


int main()
{
	int a[] = { 0,1,2,3,4 };
	printf("%x\n", a);
	printf("%x\n", &a);
	printf("%x\n", &a[0]);

	int *p = &a[0];
	
	decltype(a) t;
	decltype(&a) tt;

	cout << p << endl;
	printf("%x,%x\n", a + 1, p + 1);
	printf("%x\n", &a + 1);

	cout << sizeof(a) << " " << sizeof(&a) << endl;
}

输出

在这里插入图片描述

  • a既然是种特殊的指针,那么其打印时就会是存的地址。
  • &a的类型是int(*)[5](读法从小括号里往外,首先是指针,然后是大小为5的数组,然后数组元素类型是int),从局部变量中看到其类型也可写成int[5] *:即指向大小为5的int数组的指针。由于数组名没有内存分配空间
  • &a[0]就是取一个int对象的地址,这个int对象是数组首元素。综上所述,就造成了a &a &a[0]三者打印出来的地址是一样的。
  • p,指向数组首元素的指针。
  • a + 1,p + 1都是按照元素大小的字节数(4字节),增加4。
  • &a + 1,前面说了 &a的类型是指向大小为5的int数组的指针,大小为5的int数组所占字节数为20,所以&a + 1就应该增加20。
  • sizeof(a)为20,因为数组总的字节大小为20。
  • sizeof(&a)为4,因为&a是一种指针,指针在32位系统中占4字节。

2.4 对数组名以及取值符&的理解

数组中每个元素都是对象,即占有特定类型的内存空间。(对象,占有一块数组类型的内存空间。因为对象是指一块能存储数据并且具有某种类型的内存空间。)

数组名可以转化为这个数组对象的首个元素的地址。

这里我们不去讨论一维数组,直接从二维说起。所谓二维数组也是数组,只不过它的元素也是一个数组。

首先我们写一个二维数组留作使用


#include<iOStream>
using namespace std;
int a[][10]={
    {1,2,3,4,5,5,6,7,8,8},
    {10,12,32,42,51,15,16,71,121,18}
};

简单说明一下数组:数组a 是包含2个元素的数组,每个元素是一个包含10个 int 的数组。
既然说到数组名是其首个对象的地址那么来验证一下,测试数组名,以及对数组名求地址:


void test01(){
    cout << (long long)a << endl;         // 140273290059808
    cout << (long long)(a+1) << endl;     // 140273290059848
    // 相差40个字节
   }

(用long long 型一眼就能看出是40个字节)

aa + 1 正好相差40个字节,说明:

(1)数组名a 是(首元素{1,2,3,4,5,5,6,7,8,8})这一整行对象的地址,即首元素地址;

(2)所以在a+1偏移了一个元素大小——40字节。


void test01(){
    cout << (long long)&a << endl;        // 140273290059808
    cout << (long long)(&a+1) << endl;    // 140273290059888
    // 相差80个字节
   }

&a&a + 1 正好相差80个字节,说明:

(1)取址符取得是整个对象的地址,&a 是对二维数组求址,针对的是整个对象;

(2) &a+1 偏移一位就变成了整个二维数组的尾地址,c++中的尾地址是对象所在地址的下一位。&a+1 正好比 a 多了 80 个字节。

在上面也提到数组名会自动转换成一个特殊指针(两个表格当中的总结),接下来将理解这个指针到底是什么?

从指针解引用方面理解:


void test03(){
    cout << *a << endl;     // 0x7f051ce02020
    //为了验证,我们偏移一下
    cout << *(a + 1) << endl; // 0x7f051ce02048
    // 正好相差40个字节
}

*a 把数组名解引用之后是首元素(因为数组名是指向首元素的特殊指针),而首元素也是一个有10个元素的数组,现在 *a 是代表这个对象,输出它就是此数组的首元素——1 的地址.。


cout << *(*a) << endl; //1    **a 即可	

第二层解掉:*(*a) 自然就是第一个 int 型的元素。


cout << *a[0] << endl; //   1

因为指针指向数组对象时,可以用下标访问下一个位置,又 a 是指针指向了数组,下一个偏移为 0,即 * a = * (a + 0)


// cout << (a[0])[0] << endl; 
 cout << a[0][0] << endl;//   1

基于上述, *a 也就是a[0],也会自动转化为指向自己的首个对象(10个元素的第一个元素的位置)的指针。所以 a[0] 可以用下标访问数组对象(10个元素)内其他元素:a[0][0] == 1

我们多搞几个案例:


 // 要是访问当前行的下一个元素呢?将这个首地址
    cout << *(*a + 1) << endl;// 2 即 *((*a) + 1) 
    // 请注意这里的指针是 (*a),
    cout << (*a)[1] << endl; //    2
    // 同理(*a)相当于*(a + 0) 即a[0] 
    cout << a[0][1] << endl; //2
    
    // 如果访问下一行呢?
    cout << **(a+1) << endl;
    cout << *a[1] << endl; 
    cout << a[1][0] << endl; // *(a[1] + 0)
    
    // 第二行第二个元素呢?
    cout << *(*(a+1) +1 ) << endl;
    cout << *(a[1] +1) << endl;
    cout << a[1][1] << endl;

查看数组名类型理解


cout << typeid(*a).name()<< endl;  // A10_i
cout << typeid(&a[0]).name()<< endl; // PA10_i

A10_i :是由10个 int 组成数组
PA10_i :是一个指针类型, 指向一个数组对象,这个数组对象有10个int型的对象。编译器会识别为int(*)[10]


cout << typeid(a).name()<< endl; // A2_A10_i
cout << typeid(&a).name()<< endl; // PA2_A10_i	

A2_A10_i:由多维数组是数组的数组。A表示这个是数组类型2表示是两个对象组成的数组,每个对象(A10_i)是由有10个对象的数组,这10个对象是int型的

PA2_A10_i:是一个指针类型, 指向一个数组对象这个数组对象有2个数组型的对象。编译器会识别为int(*)[2][10]

三、字符数组数组名

c++对待字符数组名不会输出其地址,会直接输出字符


#include <iostream>
using namespace std;
 
int main()
{
	//int a[5]={1,2,34,4,5};   //如果不是char型,cout<<"a="<<a<<endl;
	// 输出的为int数组首地址。不会输出数组中的值。
	char a[5]="aaaa";         //cout重载了char[],可以输出整个字符串数组
	cout<<"a="<<a<<endl;
	return 0;
}

详细参考这篇博客

到此这篇关于详解C++数组和数组名问题(指针、解引用)的文章就介绍到这了,更多相关C++数组和数组名内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详解C++数组和数组名问题(指针、解引用)

本文链接: https://www.lsjlt.com/news/136176.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解C++数组和数组名问题(指针、解引用)
    目录一、指针 1.1 指针变量和普通变量的区别1.2 为什么需要指针1.3 指针使用三部曲二、整形、浮点型数组2.1 数组名其实是特殊的指针2.2 理解复杂的数组的声明2....
    99+
    2022-11-12
  • C++指针与数组:指针详解
    目录一. What(什么是指针)1. 地址初了解2. 指针概念3. 指针与指针变量二. Why(为什么要有指针)三. How(如何使用指针)1. 基本定义2. 取地址操作符 &...
    99+
    2022-11-12
  • 详解C++ 指针与二维数组名
    和一维数组类似,C++ 将二维数组名解释为其第一个元素的地址,而二维数组的第一个元素为一维数组,下面详细总结下二维数组名的性质。 和一维数组类似,C++ 将二维数组名解释为其第一个元...
    99+
    2022-11-13
  • C语言的数组指针与函数指针详解
    目录前言函数指针语法数组指针与指针数组总结前言 数组指针和函数指针都是C语言比较难的知识点,尤其是函数指针,并且函数指针在开发中有着巨大的作用。 函数指针语法 定义一个函数指针,并通...
    99+
    2022-11-13
  • c语言的指针数组详解
    指针如何指向数组,并读取数组中的元素: #include <stdio.h> int main() { int arr[3] = {1,2,3}; int *p;...
    99+
    2022-11-12
  • C语言中指针和数组试题详解分析
    目录数组题:程序一(一维数组):字符数组程序二(字符数组):程序三(字符数组):程序四(字符数组):程序五(字符数组):二维数组程序六( 二维数组):指针题程序七( 指针):程序八(...
    99+
    2022-11-12
  • C++中的指针问题及引用问题详解
    C++中的指针问题及引用问题详解在C++编程中,指针和引用是两个非常重要的概念。它们可以用于对变量进行间接访问,提高程序的灵活性和效率。然而,指针和引用也容易导致一些问题,本文将详细探讨这些问题,并提供具体的代码示例。指针问题:空指针访问:...
    99+
    2023-10-22
    指针问题(Pointers) 引用问题(References) C++编程(C++ programming)
  • C++中的数组引用和指针引用
    目录C++中的数组引用和指针引用一、引用的本质二、数组的引用三、指针的引用C++中的数组引用和指针引用 一、引用的本质 我们在讲解引用之前需要知道为什么C++中会单独提出引用这个概念...
    99+
    2022-11-12
  • C++数组指针和二维数组详情
    目录1、二维数组2、数组指针和二维数组1、二维数组 对于一维数组,int arr[10]; arr是数组名,也是首元素的地址,&arr是数组的地址,那么对于二维数组 int ...
    99+
    2022-11-12
  • C++中指针问题和引用问题解析
    C++中指针问题和引用问题解析引言:在C++编程中,指针和引用是两个重要的概念。它们都可以用于间接访问变量,但在使用过程中有一些差异。本文将从定义、语法、使用和特点等方面详细解析指针问题和引用问题,并提供具体的代码示例。一、指针问题解析定义...
    99+
    2023-10-22
    指针 引用 解析
  • C语言指针数组案例详解
    指针与数组是 C 语言中很重要的两个概念,它们之间有着密切的关系,利用这种 关系,可以增强处理数组的灵活性,加快运行速度,本文着重讨论指针与数组之 间的联系及在编程中的应用。 1.指...
    99+
    2022-11-12
  • C语言 指针数组进阶详解
    目录指针与数组中的sizeof与strlensizeofstrlen数组名1、一维数组整型数组字符数组指针数组2、二维数组指针笔试题 笔试题1笔试题2笔试题3笔试题4笔试题...
    99+
    2022-11-13
  • C语言指针引用数组案例讲解
    前言:C语言中指针玩的是什么,是内存,要想学好指针的小伙伴们要先对数据在内存中是怎么玩的做一番了解~       当在...
    99+
    2022-11-12
  • 【C进阶】指针和数组笔试题解析
    做题之前我们先来回顾一下 对于数组名的理解:除了以下两种情况,数组名表示的都是数组首元素的地址 (1)sizeof(数组名):这里的数组名表示整个数组 (2)&(数组名) :这里的数组名也表示整个数组 一、一维数组 int a[]...
    99+
    2023-09-26
    c语言 算法 开发语言
  • C语言sizeof和strlen的指针和数组面试题详解
    目录一、概念         sizeof:strlen:二、例题及解析2.1 一维数组2.2 字符数...
    99+
    2022-11-13
  • C#数组和指针怎么理解
    这篇文章主要讲解了“C#数组和指针怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#数组和指针怎么理解”吧!什么时候C#数组和C#指针相同所有作为函数参数的数组名总是可以通过编译器转...
    99+
    2023-06-17
  • C语言例题讲解指针与数组
    目录1.概要复习2.指针与数组笔试题2.1一维数组2.2字符数组2.3字符串数组2.4字符串指针2.5二维数组1.概要复习 本篇的内容主要围绕指针与数组、指针与字符串等之间的关系,以...
    99+
    2022-11-13
  • C语言数组指针和指针数组怎么应用
    这篇文章主要介绍“C语言数组指针和指针数组怎么应用”,在日常操作中,相信很多人在C语言数组指针和指针数组怎么应用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言数组指针和指针数组怎么应用”的疑惑有所帮助!...
    99+
    2023-06-30
  • C语言详细讲解指针数组的用法
    目录1. 指针数组定义方法2. 指针的指针(二级指针)3. 字符串和指针4. 数组指针定义方法数组指针的用法1. 指针数组定义方法 格式: 类型说明符 *数组名[ 元素个数 ] in...
    99+
    2022-11-13
  • C++中指针问题和引用问题的解决方法
    C++中指针问题和引用问题的解决方法引言:在C++编程过程中,指针问题和引用问题是常见的困扰程序员的难题。本文将介绍一些解决这些问题的方法,并通过具体的代码示例进行说明,帮助读者更好地理解和应用。一、指针问题的解决方法空指针检测在使用指针之...
    99+
    2023-10-22
    指针问题解决方法:指针 引用问题解决方法:引用 C++中的解决方法:解决方法
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作