首页 > 编程语言 >C++中的数组与指针

C++中的数组与指针

时间:2025-01-03 17:37:48浏览次数:1  
标签:arr int C++ 数组 ptr 指针

在大多数C++书籍或教程中,数组和指针的知识总是放在一起让大家学习,这是为什么,它们之间有什么联系呢?

在C++中,数组与指针有着紧密的联系,主要体现在下面几个方面:

1、数组名即指针:

本质联系:在大多数情况下,数组名会被隐式转换为指向数组第一个元素的指针。

例如,对于一个数组 int arr[5];,表达式 arr 的值是数组第一个元素的地址(等价于 &arr[0]),其类型是指向 int 类型的指针 (int*)。

这意味着可以像使用指针一样来使用数组名进行地址运算。

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // 这里将数组名arr赋值给指针ptr,ptr指向arr[0]
for (int i = 0; i < 5; i++) {
    std::cout << *(ptr + i) << " "; // 通过指针ptr访问数组元素,等价于arr[i]
}

2、通过指针访问数组元素:

相似的访问方式:通过指针的算术运算,可以像访问数组元素一样访问内存中的数据。

对指针进行加法运算(如 ptr + n),会根据指针指向的数据类型,移动相应字节数。

这与通过数组下标访问数组元素(如 arr[n])在原理上是相似的。

实际上,arr[n] 这种形式在编译器内部就是按照 *(arr + n) 来处理的。

指针运算原理

在 C++ 中,当对指针进行算术运算时,编译器会根据指针所指向的数据类型自动调整偏移量。

例如,对于int*类型的指针,ptr + 1实际上是将指针ptr的地址增加了sizeof(int)个字节。

在C++代码中,ptr是int*类型,当我们写ptr + 2时,它已经自动按照int类型的大小进行了偏移。

int类型在我们的计算机环境中是 4 字节,所以ptr + 2实际上是将ptr的地址增加了2 * sizeof(int)(即 8 字节)

例如,*(arr + i) 等价于 arr[i],表示数组中第 i 个元素。

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr;
// 以下两种方式访问数组元素效果相同
std::cout << arr[2] << " ";
std::cout << *(ptr + 2) << " ";

3、动态数组与指针:

动态内存分配:在 C++ 中,使用 new 运算符动态分配数组内存时,会返回一个指向分配内存首地址的指针。

例如,int *dynArr = new int[10]; 分配了一个包含 10 个 int 类型元素的动态数组,dynArr 就是一个指向该数组首元素的指针。

动态数组的释放也依赖于指针,使用 delete[] dynArr; 来释放通过 new[] 分配的内存。

int *dynArr = new int[10];
for (int i = 0; i < 10; i++) {
    dynArr[i] = i; // 像访问普通数组一样访问动态数组
}
// 使用完后释放动态数组
delete[] dynArr;

4、函数参数传递:

数组参数的退化:当数组作为函数参数传递时,数组会退化为指针。

例如,函数声明 void func(int arr[10]) 和 void func(int *arr) 是等价的,编译器都将其视为 void func(int *arr)。这意味着在函数内部,无法直接获取数组的长度,需要额外传递数组长度信息。

void printArray(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
}
int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    printArray(arr, 5);
    return 0;
}

5、内存布局:

数组在内存中是连续存储的,而指针可以用来遍历这些连续的内存块。
理解这一点有助于编写高效的代码,尤其是在处理大量数据时。

6、指针数组与数组指针

指针数组:是一个数组,数组中的每个元素都是指针。例如,int ptrArr[5]; 定义了一个指针数组,数组中有 5 个 int 类型的指针。常用于管理多个动态分配的数组或对象。

数组指针:是一个指针,它指向一个数组。例如,int (*arrPtr)[5]; 定义了一个指向包含 5 个 int 元素数组的指针。在处理二维数组时,数组指针会很有用,因为二维数组本质上是数组的数组。

// 指针数组
int *ptrArr[5];
for (int i = 0; i < 5; i++) {
    ptrArr[i] = new int(i);
}
// 数组指针
int arr[5] = {1, 2, 3, 4, 5};
int (*arrPtr)[5] = &arr;

为什么一起学习?

概念一致性:数组和指针的概念密切相关,一起学习可以帮助理解它们之间的内在联系,避免混淆。

实际应用:很多实际编程场景中,数组和指针常常结合使用,如字符串处理、动态内存管理等。

提高效率:理解数组和指针的关系有助于编写更高效、更灵活的代码,特别是在底层编程或性能关键的应用中。

通过同时学习数组和指针,可以更好地掌握C++的内存管理和数据操作机制,为更复杂的编程任务打下坚实的基础。

标签:arr,int,C++,数组,ptr,指针
From: https://www.cnblogs.com/zeoHere/p/18650576

相关文章

  • 14C++循环结构-while循环(1)
    一、while语句问题:试编一程序,在屏幕上输出1~5这几个数字。今天,我们用while语句来编写这个程序。while语句的特点是先判断表达式,后执行语句。其一般形式为:while(表达式)语句;当表达式的值为真(非0)时,就不断地执行循环体内的语句,所以while循环称为当型循环。while语句的执行过程......
  • 【C#】int与byte[]数组互转
    1.int转byte[]1.1C#代码//C#代码intintNum=728;byte[]byteNum=BitConverter.GetBytes(intNum);//byteNum[0]=216//byteNum[1]=2//byteNum[2]=0//byteNum[3]=01.2等效C语言代码//C语言代码intintNum=728;uint8_tbyteNum[4]={0};memcpy(byte......
  • C语言指针
    一、指针的基本概念 1. 定义 -指针是C语言中的一个重要概念,它是一个变量,其值为另一个变量的地址。简单来说,指针“指向”了内存中的某个位置,这个位置存放着其他变量的值。-例如:cinta=10;int*p;//声明一个指向int类型的指针p=&a;//将指针p指向变量a的地......
  • C中如何理解指针和引用的区别?
    在C语言中,指针和引用是两个重要的概念,它们都与内存地址和变量之间的关系有关,但它们在定义、使用和特性上存在显著的区别。下面将详细解释指针和引用的区别,并通过示例代码进行说明。指针的基本概念指针是一种变量,其值为另一个变量的地址,即内存位置。通过使用星号(*)声明指针变量......
  • 用c++实现四阶龙格库塔方法求解常微分方程
    `#includeusingnamespacestd;doublefunc(doublex,doubley)//自定义函数{if(x==0)return1;returny-(2*x)/y;}void龙格库塔(doublea,doubleb,intn)//a~b范围内的函数求值,n为求值的次数;{//初始化doubleK[4]={0.0,0.0,0.0,0.0};doubleh=(b......
  • C++vector的常用接口及其介绍
    在C++中,vector 是一个非常常用的动态数组容器,它定义在 <vector> 头文件中。以下是 vector 的一些常用接口及其介绍:构造函数vector():默认构造函数,创建一个空的 vector。std::vector<int>v;vector(size_typen,constvalue_type&val=value_type()):创建一个包......
  • 数组中的第k个最大元素(快速排序)
    给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例1:输入:[3,2,1,5,6,4],k=2输出:5示例 2:输入:[3......
  • c++之左值引用 右值引用 万能引用
    详细大家无论是在阅读代码,还是阅读文档的时候经常看到这几个词或者对应的符号,但是可能也不是很清楚他们到底有哪些区别,本文将对这几个概念详细深入的介绍。左值引用左值引用的表现形式,如下所示:intx=2;int&a=x; //正确,这里a就是一个左值引用int&a=2;//错误,临......
  • C++之模板进阶
    文章目录1.引言2.非类型模板参数2.1概念及使用2.2与#define定义宏的对比3.模板的特化3.1概念3.2函数模板特化3.3类模板特化3.3.1全特化3.3.2偏特化(也称半特化)3.3.3类模板特化应用示例4.模板的分离编译(了解)4.1什么是分离编译4.2模板的分离编译5.模......
  • 多维数组、锯齿数组
    C++多维数组定义:多维数组可以看作是数组的数组,通过在定义时指定每个维度的大小来创建。下面以三维数组为例。访问:使用多个索引来访问数组中的元素,索引从0开始。销毁:对于栈上定义的多维数组,当作用域结束时会自动销毁;对于堆上动态分配的多维数组,需要手动释放内存。#include<......