简介

以下三行代码有什么区别?

int a[10];
int *a = (int*)malloc(sizeof(int)*10);
int *a = new int[10];
  • 第一行代码定义a为包含10个int类型元素的整形数组。
  • 第二行和第三行分别使用的是C和C++来定义动态数组,他们的结果是相同的。a都可以表示为一个动态数组。

我们可以使用a[1]来取数组a的第1个元素。那他们有什么区别呢?


解释

我们从指针开始说起。所谓指针,就是用来存放内存地址的一个变量,首先,指针是个变量;其次,指针存放的是内存地址。

指针的定义中包含了一个重要的说明:指针中存放的内存地址处的内容应该如何解析。例如:int *a; 说明a是一个指针,他存放的地址处的数据被解析为一系列连续的int型数据。

int a[10],可以说明a是一个指针么?其实,这样说是不准确的。a其实本身就是一个内存地址。只是我们在实际运行之前并不知道他真正代表哪个地址。就像宏在编译的时候被替换成宏定义的内容,静态数组a实际上在执行的时候是被替换成真实的内存地址的。也就是说a已经是内存地址了,不是变量。

那么对于int a[10]int *b = new int[10]a[2]b[2]有什么区别呢?

  1. a[2]b[2]在赋值符号=的右端的时候。此时表示取a[2]b[2]的值。对于a[2],首先a代表的是个内存地址,在这个内存地址处偏移sizeof(int)*2个字节,取连续sizeof(int)个字节,并将其解析为int类型的数。对于b[2],首先b是一个指针,其值是一个内存地址,首先b这个变量在内存中的地址被找到,然后取连续的sizeof(int*)个字节,解析为一个内存地址,然后在这个地址处偏移sizeof(int)*2个字节,取连续sizeof(int)个字节,并将其解析为int类型的数。
  2. a[2]b[2]在赋值符号=的左端的时候。表示向相应的内存位置赋值。赋值符号右端的表达式的结果不管是什么类型的值,都会被默认强制类型转化为int型数据。对于a[2]a代表的是个内存地址,在这个内存地址处偏移sizeof(int)*2个字节,向连续的sizeof(int)个字节内存中写入赋值号右端的结果。对于b[2],首先b这个变量在内存中的地址被找到,然后取连续的sizeof(int*)个字节,解析为一个内存地址,然后在这个地址处偏移sizeof(int)*2个字节之后,向连续的sizeof(int)个字节内存中写入赋值号右端的结果。

实验

试验下前面讨论的内容:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(int argc, char** argv){
    int a[10];
    printf("%.16X\n", (uint64_t)(&a));
    printf("%.16X\n", (uint64_t)(a));
    int *b = new int[10];
    printf("%.16X\n", (uint64_t)(&b));
    printf("%.16X\n", (uint64_t)(b));
    delete[] b; b = NULL;
    return EXIT_SUCCESS;
}

某次执行结果:

000000003093F838
000000003093F838
000000003093F878
00000000309A8D90

根据输出结果,可以推断,a&a的值是相同的,说明a已经是地址了,取地址后还是原先的地址,所以两次地址是一样的。

后两次输出结果不同,是应为b是一个指针,是变量,变量的地址与他存储的内存地址是不同的。

C/C++静态数组与动态数组的区别的更多相关文章

  1. JS 索引数组、关联数组和静态数组、动态数组

    JS 索引数组.关联数组和静态数组.动态数组 数组分类: 1.从数组的下标分为索引数组.关联数组 var ary1 = [1,3,5,8]; //按索引去取数组元素,从0开始(当然某些语言实现从1开始 ...

  2. "《算法导论》之‘队列’":队列的三种实现(静态数组、动态数组及指针)

    本文有关栈的介绍部分参考自网站数据结构. 1. 队列  1.1 队列的定义 队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表. (1)允许删除的一端称为队头(Front) ...

  3. solidity定长数组和动态数组

    固定长度的数组 固定长度数组声明 直接在定义数组的时候声明固定长度数组的值: uint[5] fixedArr = [1,2,3,4,5]; 可通过数组的length属性来获得数组的长度,进而进行遍历 ...

  4. VS中Debug和Realease、及静态库和动态库的区别整理(转)

    原文出自:http://www.cnblogs.com/chensu/p/5632486.html 一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不 ...

  5. VS中Debug和Realease、及静态库和动态库的区别整理

    一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程序在代码 ...

  6. iOS 静态库和动态库的区别&静态库的生成

    linux中静态库和动态库的区别 一.不同 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函 ...

  7. jsp中静态include和动态include的区别

    jsp中静态include和动态include的区别 动态 INCLUDE 用 jsp:include 动作实现 <jsp:include page="included.jsp&quo ...

  8. JSP页面静态包含和动态包含的区别与联系

    ---恢复内容开始--- JSP页面静态包含和动态包含的区别与联系: 1.<%@ include file=" " %> 是指令元素,<jsp:include p ...

  9. iOS中的静态库与动态库,区别、制作和使用

    如果我们有些功能要给别人用,但是又不想公开代码实现,比如高德地图.第三方登录分享等等,这时候我们就要打包成库了.库分静态库和动态库两种: 静态库:以.a 和 .framework为文件后缀名.动态库: ...

  10. iOS 中的静态库与动态库,区别、制作和使用

    如果我们有些功能要给别人用,但是又不想公开代码实现,比如高德地图.第三方登录分享等等,这时候我们就要打包成库了.库分静态库和动态库两种: 静态库:以.a 和 .framework为文件后缀名.动态库: ...

随机推荐

  1. springboot集成jpa

    spring data jpa简介 spring data jpa是spring基于hibernate及jpa规范封装出来的一套持久层框架.该框架极大的降低了开发者工作量,提升开发效率.提供的关键字可 ...

  2. python入门编程之三级菜单编程

    菜单实现功能输入一层显示下一层菜单不论在哪层输入b返回上一层不论在哪层输入q退出菜单此代码通过利用字典的知识可以实现_Author_ = 'jc'data = { '北京':{ '昌平':{ '沙河' ...

  3. 个人建站&mac下安装hexo

    title: 个人建站&mac下安装hexo date: 2018-04-18 16:34:02 tags: [mac,blog,个人建站,markdown] --- 这两天使用了markdo ...

  4. 洛谷P3159 [CQOI2012]交换棋子

    巧妙的拆点方式,首先把1看成黑点,0看成空的,几次交换就可以看成一条路径 1)从容量上看,这条路径为1-2-2-2-2-2----2-1 2)从费用上看,这条路径每条边费用都是1 于是用一种巧妙的拆点 ...

  5. UVA - 11992:Fast Matrix Operations

    线段树,注意tag优先级 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cs ...

  6. 【BZOJ4034】【HAOI2015】树上操作

    题目请自行查阅传送门. 典型的树剖题,线段树维护操作,记一下子树在线段树内范围即可. 时间复杂度:\( O(m \log^{2} n) \) #include <stdio.h> #def ...

  7. Linux上安装Libssh2

    由于项目需要使用libssh2,在安装时,遇到一些问题,发现网上的都是互相抄,把自己遇到的问题,记下来,希望可以帮助到别人,自己下次使用时候,也方便查找,节约时间. 安装的流程: 1.下载源码,wge ...

  8. 习题10-1 UVA 11040(无聊水一水)

    题意: 给你一个残缺的塔,每个数字由他下面左右两个数相加得.给你其中一部分,要求输出全部的数字. #include <iostream> #include <cstdio> # ...

  9. BZOJ3052(树上带修莫队)

    树上莫队的基本思路是把树按dfs序分块,然后先按x所在块从小到大排序,再按y所在块从小到大排序,处理询问即可. 这道题带修改,再加一个时间维即可. 设块大小为T,那么时间复杂度为$O(nT+\frac ...

  10. Python中str字符串的功能介绍

    Str字符串的功能介绍 1. 字符串的操作 字符串的连接操作 符号: + 格式:str1 + str2 例如:str1 = 'I Love' str2 = 'You!' print(str1 + st ...