浅谈C/C++中指针和数组的不同

 更新时间:2020年05月29日 14:15:01   作者:Van0512  
本文主要解析了C/C++中数组和指针的区别,文章简单易懂,对各位的工作学习有所帮助,有需求的朋友可以了解下

这边先简单介绍一下内存分区。

内存按照用途划分为五个区:

1.栈区:由系统控制分配和回收。

例如定义变量 int x = 0; int *p = NULL; 变量所占的内存都是分配在栈区的。

2.堆区:由程序员管理。

在C语言中由 malloc 申请的内存,或者在C++中,用 new 申请的内存,是在堆区中申请的。用完之后需要程序员自己回收,否则会造成内存泄漏。

3.全局区:存储全局变量及静态变量

4.常量区:存储常量。

5.代码区:存储编译之后的二进制代码。

数组和指针具有很大的相似性,实际上,数组也是一种指针,一种有点特别的指针。
例如,可以这样申请包含10个 int 型数据的数组

//方式1
int arr[10]; //栈区
//方式2
int *ptr = new int[10]; //堆区

我们也常常在定义一个函数的时候使用指针,而传入实参(argument)的时候使用数组(甚至函数的声明和定义可以用指针和数组混搭)。例如:

void func(int *ptr, int n) {
 //statements
}

int main(void) {
 int arr[10];
 ...
 func(arr, 10);
 return 0;
}

数组名代表着一个地址,是其所占内存单元的首地址。在上例中,arr 和 &arr[0] 是相同的。

数组名表示一个地址,这一点和指针一样。不一样的地方在于数组名是一个固定的地址,数组是存放在栈区的,其地址不能改变,也即是一个 const 。
在用一个指针指向数组的时候,可以有几种形式。

int arrInt[10];
/*
ptr1 和 arrInt 的值是一样的,都是同一块内存空间的首地址。
这种形式规定了 ptr1 指向了一个包含10个元素的整形数组,书写麻烦,同时也限制了指针,因此很少用。
*/
int (*ptr1)[10] = &arrInt;
/*
这种形式就是我们比较熟悉和喜闻乐见的了。
在前面一块代码中,在实参中传入数组名,实际上做了这样一件事情:
int *ptr = arrInt; 形式参数是一个指向了 arrInt 的指针。
重点要解释的地方在下一块代码中说明~~~
*/
int *ptr2 = arrInt;

在C++中,有一种引用类型,相当于给变量取了个别名,在传递参数的时候就不会拷贝参数,提高了效率,减少了内存开销。
显而易见,在传递数组参数的时候,可以使用数组的引用。
数组的引用也有不同的方式:

int arrInt[10];
//和指向数组的指针的第一种定义方式类似
int (&ref1)[10] = arrInt;
//这样写怎么样?
int *&ref2 = arrInt;
/*
编译器会报错:
invalid initialization of non-const reference of type 'int*&' from an rvalue of type 'int*'.
原因在于,在栈区中的数组 arrInt 由系统控制,它的地址不能改变。
如果上面的代码可以通过,就意味着可以通过 ref2 指向其他的地址,从而修改 arrInt 的内存地址,这是不允许的,所以编译不通过。
*/
/*
可以这样做。
ref3 是一个引用,并且是一个常量的引用,引用的是一个 int* 。
由于 ref3 是一个常量引用,它的值不允许被修改,因此 ref3 就能够引用 arrInt。
*/
int * const &ref3 = arrInt;

啰啰嗦嗦讲了这么多,其实就一句话——
在栈区中的数组是一种不能改变地址的指针,或者说是一种 const 指针。
o(╯╰)o
(再多一句~~~)
而在堆区中动态申请内存的数组,也就是我们平时在用的指针。

以上就是浅谈C/C++中指针和数组的不同的详细内容,更多关于c/c++ 指针和数组的资料请关注脚本之家其它相关文章!

相关文章

  • C语言详细讲解指针数组的用法

    C语言详细讲解指针数组的用法

    在C语言和C++等语言中,数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活
    2022-05-05
  • 深入理解C语言的new[]和delete[]

    深入理解C语言的new[]和delete[]

    new和delete既是C++中的关键字也是一种特殊的运算符。这篇文章主要介绍了C++的new和delete详解,需要的朋友可以参考下
    2021-09-09
  • Qt5多线程编程的实现

    Qt5多线程编程的实现

    Qt通过三种形式提供了对线程的支持,本文主要介绍了Qt5多线程编程的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • C++中如何使用引用避免内存复制

    C++中如何使用引用避免内存复制

    C++引用是一种强大的工具,可以避免在函数调用过程中发生的常见内存复制问题,本文主要介绍了C++中如何使用引用避免内存复制,感兴趣的可以了解一下
    2023-10-10
  • VC实现让关闭按钮成灰色不可用的方法

    VC实现让关闭按钮成灰色不可用的方法

    这篇文章主要介绍了VC实现让关闭按钮成灰色不可用的方法,比较实用的一个特殊功能,需要的朋友可以参考下
    2014-08-08
  • C++学习之移动语义与智能指针详解

    C++学习之移动语义与智能指针详解

    智能指针和移动语义是迄今为止,最难理解的两个概念,下面这篇文章主要给大家介绍了关于C++学习之移动语义与智能指针的相关资料,需要的朋友可以参考下
    2021-05-05
  • C/C++中宏定义(#define)

    C/C++中宏定义(#define)

    #define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。接下拉通过本文给大家分享C/C++中宏定义(#define)知识,需要的朋友参考下
    2017-02-02
  • C语言实现数据结构串(堆分配存储表示法)实例详解

    C语言实现数据结构串(堆分配存储表示法)实例详解

    这篇文章主要介绍了C语言实现数据结构串(堆分配存储表示法)实例详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • C语言字符串快速压缩算法代码

    C语言字符串快速压缩算法代码

    这篇文章主要介绍了C语言字符串快速压缩算法代码,将字符串中连续出席的重复字母进行压缩,其主要的压缩字段的格式为”字符重复的次数+字符”。有需要的小伙伴参考下吧。
    2015-03-03
  • c++ 构造函数的初始化列表

    c++ 构造函数的初始化列表

    构造函数的初始化列表仅仅指定用于初始化成员的值,并不指定这些初始化执行的次序。成员初始化的次序就是定义成员的次序,第一个成员首先被初始化,然后是第二个,依次类推
    2013-07-07

最新评论