从计算理解数组

从计算理解数组

公式法(基础)

数组是我们C语言中最常用的数据结构之一,我们必须熟练掌握.

数组名就是这整个数组的首地址,这里我们记为a, 我们常常苦恼 a+1,&a+1,a[0]+1究竟指向的是哪个元素.

我曾试图写出所有数组的首地址通项转换公式,但发现写出来的意义不大,不容易记,只是摆着好看,而我们平常用得最多的数组的维度都不会超过三维,那么我们只要把握低维度的公式就足以应付日常编程了.

由于一维过于简单,这里就不讨论了,只着重讨论二维和三维数组.

运用下面的公式,可以准确算出数组首地址变化后的值.

符号的定义:
T       表示任意的类型
a       表示数组的首地址
k       表示某一偏移量
SIZET   表示T类型的大小(单位字节)
val(x)  表示x的值,下面表示数组首地址的值
m,n,k   表示任意自然数

1583308166542

补充公式(解引用与数组引用转换公式):

对任一数组a来说,取自然数q,m,n,k,均满足 
a[m]+k          <=>     *(a+m)+k
a[m][n]+k       <=>     *(*(a+m)+n)
a[q][m][n]+k    <=>     *(*(*(a+q)+m)+n)+k

直观法(推荐)

从数字中把握数组是准确的,但是却并不直观,下面是直观对数组首地址的运算的理解

T****   //体  元素
T***    //面  元素
T**     //行  元素
T*      //个  元素
T       //值  

例如 T* + 1 则表示跳到下一个元素

例如 T** + 1 则表示跳到下一行元素(究竟跳过了多少个元素由一行中有多少个元素决定)

每当想要得知指向哪一个元素时,先判断类型,再根据类型进行推理,这种直观方法会更常用一些.

具体是,忽略类型的大小(即SIZET),代之以元素的个数来表示偏移的距离,从而推算出指向了哪个元素.

代码

下面给出测试代码以验证公式的准确性,不包含解引用与数组引用转换公式

#include "pch.h"
#include<stdio.h>
#include <iostream>
using namespace std;

#define q 5
#define m 4
#define n 3
const int k = 2;
typedef int T;

int main()
{
    T a[m][n];
    T b[q][m][n];

    const int valueofa = (int)a;
    printf("value of a: %d\n", valueofa);

    const int valueofb = (int)b;
    printf("value of b: %d\n", valueofb);
    const int SIZET = sizeof(T);
    printf("SIZET: %d\n", SIZET);

    printf("\n\n");

    //atest
    printf("&a+k :  %d --- %d+%d*%d*%d*%d\n", &a + k,valueofa,k,m,n,SIZET);
    printf("a+k  :  %d --- %d+%d*%d*%d\n", a + k, valueofa, k, n, SIZET);
    printf("*a+k :  %d --- %d+%d*%d\n", *a + k, valueofa, k, SIZET);
    
    printf("\n\n");

    //btest
    printf("&b+k :  %d --- %d+%d*%d*%d*%d*%d\n", &b + k, valueofb, k, q, m, n, SIZET);
    printf("b+k  :  %d --- %d+%d*%d*%d*%d\n", b + k, valueofb, k,m, n, SIZET);
    printf("*b+k :  %d --- %d+%d*%d*%d\n", *b + k, valueofb, k,n, SIZET);
    printf("**b+k:  %d --- %d+%d*%d\n", **b + k, valueofb, k, SIZET);

    return 0;
}

执行结果:

value of a: 19921648
value of b: 19921400
SIZET: 4


&a+k :  19921744 --- 19921648+2*4*3*4
a+k  :  19921672 --- 19921648+2*3*4
*a+k :  19921656 --- 19921648+2*4


&b+k :  19921880 --- 19921400+2*5*4*3*4
b+k  :  19921496 --- 19921400+2*4*3*4
*b+k :  19921424 --- 19921400+2*3*4
**b+k:  19921408 --- 19921400+2*4

猜你喜欢

转载自www.cnblogs.com/virgildevil/p/12410266.html