·引 对数组的认知

在c语言中,我们经常使用的一个结构便是数组,在最开始学习数组的时候,它被描述成这样(以一维二维数组为例):
一维数组是若干个数连续排列在一起的集合,我们可以通过0-N的标记(N为数组的长度)来访问每一个元素。
二维数组则是一维数组的集合。
所以在最开始我们对二维数组的概念是这样的:

然后推而广之到三维数组

很合理的,我们通过**空间结构**去类比数组的一维与二维,那么问题来了,在计算机当中它又是怎么“类比”这些数组的呢?
我们先看一些代码

#include <stdio.h>
int main(void)
{
int a[5][5];
for(int i=0,num=0;i<5;i++)
for(int j=0;j<5;j++,num++)
a[i][j]=num;
for(int i=0;i<5;i++){
for(int j=0;j<5;j++)
printf("%5d",a[i][j]);
printf("\n");
}
printf("\na[ 1][ 1]=%2d %p\n",a[1][1],&a[1][1]);
printf("a[ 1][ 2]=%2d %p\n",a[1][2],&a[1][2]);
printf("a[ 1][ 3]=%2d %p\n",a[1][3],&a[1][3]);
}
``` ```
运行结果:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24 a[ 1][ 1]= 6 000000000062FDE8
a[ 1][ 2]= 7 000000000062FDEC
a[ 1][ 3]= 8 000000000062FDF0

这个结果是显而易见的,而通过对地址的观察,我们发现每两个相邻的数其间距为4个字节,也验证了我们认为它是连续的这一认知。而按照约定进行访问也是我们一般的使用方法。

· 扩展

接下来我们将输出本部分替换成以下代码

//这里我们将研究标记如果使用负数将会是什么情况
printf("a[ 0][ 0]=%2d %p\n",a[0][0],&a[0][0]);
printf("a[ 0][-1]=%2d %p\n",a[0][-1],&a[0][-1]);
printf("a[-1][ 0]=%2d %p\n",a[-1][0],&a[-1][0]);
printf("a[-1][-1]=%2d %p\n",a[-1][-1],&a[-1][-1]);
```
一次运行实例
```
a[ 0][ 0]= 0 000000000062FDD0
a[ 0][-1]= 0 000000000062FDCC
a[-1][ 0]= 0 000000000062FDBC
a[-1][-1]= 0 000000000062FDB8
```
或者我们再对a[4][4]进行越界研究,代码: ```
printf("a[ 4][ 4]=%2d %p\n",a[4][4],&a[4][4]);
printf("a[ 4][ 5]=%2d %p\n",a[4][5],&a[4][5]);
printf("a[ 5][ 4]=%2d %p\n",a[5][4],&a[5][4]);
printf("a[ 5][ 5]=%2d %p\n",a[5][5],&a[5][5]);
```
一次运行实例 ```
a[ 4][ 4]=24 000000000062FE30
a[ 4][ 5]= 0 000000000062FE34
a[ 5][ 4]= 5 000000000062FE44
a[ 5][ 5]=25 000000000062FE48
```

实际上这些结果是恰恰符合我们的预期的,因为他们使用的下标超出了数组范围,所以自然访问到了数组外内存中的数,这些数是大部分是随机的。
就像这样

但是对于以下这些代码:

```
printf("a[ 1][ 0]=%2d %p\n",a[1][0],&a[1][0]);
printf("a[ 1][-1]=%2d %p\n",a[1][-1],&a[1][-1]);
printf("a[ 1][-2]=%2d %p\n",a[1][-2],&a[1][-2]);
```

其输出结果为

```
a[ 1][ 0]= 5 000000000062FDE4
a[ 1][-1]= 4 000000000062FDE0
a[ 1][-2]= 3 000000000062FDDC
```

考虑之前的类比,这样的结果显然是不合理的,因为如果是二维结构,那么我们所输出的结果应该为一个内存中的随机值,但是根据观察原数组:

```
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
```

我们恰恰可以发现它a[1][-1]与a[1][-2]输出的恰恰是a[0][4]与a[0][3]的内容。也就是说我们退回了上一行
其实这些问题的答案在观察数组的地址时就能找到答案:
000000000062FDE0 - 000000000062FDE4= 4 = sizeof(int)
显然这意味着这是内存空间中连续的地址,也就是说二维数组真正的储存方式任然是线性的,一维的,同理我们可以得知对于三维,乃至更高维的数组,它其实也无法跳出维度的限制,其实他们都是一维
所以我们应该这样认识多维数组

(其实这些都是很简单的东西,但是为此总结一下深化一下印象。因为很多时候第一印象往往是错的,正如二维数组并不是二维)

C语言中数组使用负数值的标记的更多相关文章

  1. 对于C语言中数组名是指针的理解

    我们都知道,c语言中数组名是一个指针,比如下面这段代码 #include<iostream>using namespace std;int main(){ int a[4]={1,2,3, ...

  2. c语言中数组相关问题

    c语言中数组相关问题: 1.数组基本定义: 相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标.组成数组 ...

  3. C语言中数组与指针的异同之处!你不知道的编程奥秘~

    C语言的数组和指针一直是两个容易混淆的东西,当初在学习的时候,也许为了通过考试会对指针和数组的一些考点进行突击,但是很多极其细节的东西也许并不是那么清楚.本篇侧重点在于分析数组与指针的关系,什么时候数 ...

  4. C语言中数组长度不能用变量定义吗?

    C语言里,所有变量空间都是在程序运行之初向系统申请的,包括指针,除了一些动态申请方式如malloc函数.没有申请的空间系统是不允许读写的.那么如果一个数组大小是变量定义,则在程序运行前不能确定数组大小 ...

  5. C++ - C语言中数组的另一种常用写法(数组大小可变!!!)

    在 C 和 C++ 中,数组在声明过程中,数组名称为 const 指针,不许修改.且数组的大小在声明时被写死,非常不方便. C语言中常用下面代码替代指针. #include <stdio.h&g ...

  6. c语言中数组的定义和java中数组定义的一些区别

    感谢原文:https://blog.csdn.net/gzwdz778/article/details/79799408 一维情况下: c中,数组的声明需要给出数组的维数,比如: int arr[5] ...

  7. 别人不会给你说的---C语言中数组名和指针的区别 及 sizeof用法

    引自: http://blog.csdn.net/tianyue168/article/details/5781924 #i nclude <iostream.h> int  main( ...

  8. C++语言中数组指针和指针数组彻底分析

    #################################                              ##       基本知识               ##        ...

  9. Go语言中数组的内部实现和基础功能

    数组的内部实现和基础功能 因为数组是切片和映射的基础数据结构.理解了数组的工作原理,有助于理解切片和映射提供的优雅和强大的功能. 内部实现 在Go语言里,数组是一个长度固定的数据类型,用于存储一段具有 ...

随机推荐

  1. vue+element-ui实现显示隐藏密码

    <template> <el-form :model="cuser_info" label-width="115px" label-posit ...

  2. Git安装与仓库搭建

    yum install git-all cd /srv git init --bare net_server.git git remote - v git remote add server root ...

  3. 将Python3导出为exe程序

    一.pyinstaller简介 Python是一个脚本语言,被解释器解释执行.它的发布方式: .py文件:对于开源项目或者源码没那么重要的,直接提供源码,需要使用者自行安装Python并且安装依赖的各 ...

  4. 一些C语言基础知识

    位运算 // 按位与&: 2 & 3 = 2: 010 & 011 = 010   两个1才为1 // 按位或|: 2 | 3 = 3: 010 | 011 = 011   只 ...

  5. Luogu P2158 仪仗队 题解报告

    题目传送门 [题目大意] 给定一个n×n的点方阵,求站在左下角的点能看到的点数 注意同一条直线上只能看到一个点 [思路分析] 因为是一个方阵,所以可以对称地算,那么对于半个方阵,这里假设是左上的半个方 ...

  6. Python 高级特性之:生成器(generator)和迭代器(Iterator)

    前言: 之前学习Python自动化,接触了不少python的学习,对生成器印象尤其深,网上也看了很多介绍,下面主要是这些概念的个人学习整理(如侵删). 正文: 如要创建一个非常大的列表,受到内存限制, ...

  7. 【尚学堂·Hadoop学习】MapReduce案例1--天气

    案例描述 找出每个月气温最高的2天 数据集 -- :: 34c -- :: 38c -- :: 36c -- :: 32c -- :: 37c -- :: 23c -- :: 41c -- :: 27 ...

  8. (一)ORB描述子提取

    ORBSLAM2中使用ORB描述子的方法 经典的视觉SLAM系统大体分为两种:其一是基于特征点法的,其二是基于直接法的.那么本文主要就讲特征点法的SLAM. 基于特征点法的视觉SLAM系统典型的有PT ...

  9. Android Wear 2.0 AlarmManager 后台定时任务

    以前在Android 4.0时,alarmManager 没什么问题.后来android为了优化系统耗电情况,引入了doze模式,参见此页 https://developer.android.com/ ...

  10. Ipa 脱壳工具 Clutch dumpdecrypted 使用

    1  Clutch 使用 下载地址 : https://github.com/kjcracks/clutch/releases 下载之后去掉去掉版本号 拖入手机的 /usr/bin/ 目录下 执行 c ...