zoukankan      html  css  js  c++  java
  • 从计算理解数组

    从计算理解数组

    公式法(基础)

    数组是我们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)+k
    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
    ", valueofa);
    
    	const int valueofb = (int)b;
    	printf("value of b: %d
    ", valueofb);
    	const int SIZET = sizeof(T);
    	printf("SIZET: %d
    ", SIZET);
    
    	printf("
    
    ");
    
    	//atest
    	printf("&a+k :  %d --- %d+%d*%d*%d*%d
    ", &a + k,valueofa,k,m,n,SIZET);
    	printf("a+k  :  %d --- %d+%d*%d*%d
    ", a + k, valueofa, k, n, SIZET);
    	printf("*a+k :  %d --- %d+%d*%d
    ", *a + k, valueofa, k, SIZET);
    	
    	printf("
    
    ");
    
    	//btest
    	printf("&b+k :  %d --- %d+%d*%d*%d*%d*%d
    ", &b + k, valueofb, k, q, m, n, SIZET);
    	printf("b+k  :  %d --- %d+%d*%d*%d*%d
    ", b + k, valueofb, k,m, n, SIZET);
    	printf("*b+k :  %d --- %d+%d*%d*%d
    ", *b + k, valueofb, k,n, SIZET);
    	printf("**b+k:  %d --- %d+%d*%d
    ", **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
    
  • 相关阅读:
    为什么说2013是PHP年
    wordpress 投稿插件 支持图片上传
    php简易页面内调试技巧
    WordPress中文文档
    百度网盘文件直链
    HOWTO:如何解决安装包在系统“添加/删除”中无法修复或卸载的问题
    InstallShield 2008 终止声明 (EOL)对最终客户意味着什么
    InstallShield 2011新功能试用(10) Express版本
    AdminStudio 9.5 Service Pack 3
    INFO:InstallShield中安装路径变量的区别
  • 原文地址:https://www.cnblogs.com/virgildevil/p/12410266.html
Copyright © 2011-2022 走看看