C/C++静态数组与动态数组的区别
2016-04-25 19:11
274 查看
简介
以下三行代码有什么区别?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]有什么区别呢?
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类型的数。
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是一个指针,是变量,变量的地址与他存储的内存地址是不同的。
相关文章推荐
- 抽象工厂的初次尝试 ((15c++ Homework) polymorphic and OOP design pattern Abstract Factory)
- C++ 语法学习 2
- c语言 按格式读取文件内容
- c++第四次作业
- 【akMOOC】2 多条printf输出
- C++实验四----乘法口诀表
- C/C++获取当前系统时间
- c++的输入与输出,/r与/n的区别
- C语言解决螺旋矩阵算法问题的代码示例
- C++第四次作业
- 1.4.C语言如何操作内存
- C语言结构体复习
- c++ 副作用和顺序点
- 杭电2024 2025 2026(关于while,gets循环的一些技巧)
- 嵌入式C语言笔试题
- 双向链表的相关操作C++实现
- c++实验4-输出星号图
- C++模板的坑
- C/C++ 打印文件名、行号、函数名的方法
- 使用GDB调试Android NDK native(C/C++)程序