二维数组的认识及其表示元素的两种方式

/*
 ============================================================================
 Name        : TeatArr.c
 Author      : lf
 Version     :
 Copyright   : Your copyright notice
 Description : 二维数组的认识以及其表示元素的两种方式
  备注说明
 1 要理解二维数组的存储方式.
 2 实际上利用a[i][j]的方式并不"正统",这是这靠近我们的
        常识一些,更本质和应该是还是利用指针.

  参考资料:
 http://blog.csdn.net/iu_81/article/details/1782642
 http://www.jb51.net/article/54220.htm
 Thank you very much
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	test1();
	test2();
	test3();
	return EXIT_SUCCESS;
}

/**
 * 一维数组的两种表达方式
 * int *p=&a
 * 指针p执行了数组a的首元素.
 * 又因为*p是取内容,所以*(p+N)
 * 取的就是第N个元素的内容
 */
void test1(){
	int a[5]={0,1,2,3,4};
	//第一种方式:下标表示法
	int i=a[2];
	printf("i=%d\n",i);

	//第二种方式:指针表示
	int *p=&a;
	int j=*(p+2);
	printf("j=%d\n",j);
	printf("==========\n");

	//在一维数组中数组名就是首元素的地址
	//所以a和&a[0]是等值的.
	//但是注意&a虽然值和它们两个相等,但是它是
	//代表整个数组的块地址的起始值.
	//这点通过sizeof()可以看出来
	printf("a=%x,sizeof(*a)=%d\n",a,sizeof(*a));
	printf("&a[0]=%x,sizeof(*&a[0])=%d\n",&a[0],sizeof(*&a[0]));
	printf("&a=%x,sizeof(*&a)=%d\n",&a,sizeof(*&a));
	printf("==========\n");

    //&a是一个地址,再执行*&a还是得到这个地址.在数值上也等于a
	printf("&a=%x\n",&a);
	printf("*&a=%x,sizeof(*(*&a))=%d,a=%x\n",*&a,sizeof(*(*&a)),a);
	printf("==========\n");

}

/**
 * 二维数组的认识
 *
 * 关于二维数组的指针表示方式,简述如下:
 * 二维数组的每个元素是一个一维数组.
 * 比如此处的a[3][4]可以看成是有3个元素的一维
 * 数组,每个元素又是具有4个元素的一维数组.
 * 所以此时可把二维数组a[3][4]看作一维数组a[3]
 * 这个一维数组有三个元素,每个元素又是一个一维数组.
 * 在此打印每行的地址:
 * &a[0]=28feb0
 * &a[1]=28fec0
 * &a[2]=28fed0
 * 可以看到每行的地址相差4*4=16
 * 但是为什么
 * a[0]=28feb0
 * a[1]=28fec0
 * a[2]=28fed0
 * 也打印出来了每行的地址???
 * 这个很简单,在test1()中已经进行了说明:
 * &a是一个地址,再执行*&a还是得到这个地址.
 * 即&a[0]=*&a[0]在数值上也等于a
 * 所以&a[i]与*(&a[i])和a[i]是同一回事!!!
 *
 * 因为a是指向第一行的地址,所以a+1代表第二行的地址,a+2代表第三行的地址
 * 所以&a[i]与a+i是同一回事!!
 *
 * 综上所述:
 * 在二维数组a中
 * &a[i]与*(&a[i])和a[i]还有a+i是等价的
 *
 * 由此可以看到两条演变的路线:
 * &a[i]-->*&a[i]-->a[i]
 * &a[i]-->*&a[i]-->*(&a[i])-->*(a+i)
 *
 */
void test2(){

	int a[3][4] = { { 0, 1, 2, 3 },
				    { 4, 5, 6, 7 },
				    { 8, 9, 10, 11 } };
	//打印二维数组每一行的首地址.&a[i]与a+i等价
	printf("&a[0]=%x,a+0=%x\n",&a[0],a+0);
	printf("&a[1]=%x,a+1=%x\n",&a[1],a+1);
	printf("&a[2]=%x,a+2=%x\n",&a[2],a+2);

	printf("&a[0]=%x,a[0]=%x,*(a+0)=%x\n",&a[0],a[0],*(a+0));
	printf("&a[1]=%x,a[1]=%x,*(a+1)=%x\n",&a[1],a[1],*(a+1));
	printf("&a[2]=%x,a[2]=%x,*(a+2)=%x\n",&a[2],a[2],*(a+2));

	printf("==========\n");
}

/**
 * 二维数组的两种表达方式
 *
 * 利用下标方式访问i行j列的数据很简单:a[i][j]
 *
 * 如果用指针的方式又该是怎么样呢?
 * 第一步:找到行
 * 从test2()中我们已经知道了行地址是*(a+i)
 * 第二步:找到列
 * 找到了行再找列就简单多了,偏移j个单位就行
 *
 * 于是地址为*(a+i)+j,取值为*(*(a+i)+j);
 *
 */
void test3(){
	int a[3][4] = { { 0, 1, 2, 3 },
			        { 4, 5, 6, 7 },
			        { 8, 9, 10, 11 } };

	//第一种方式:下标表示法
	int i=a[2][3];
	printf("i=%d\n",i);

	//第二种方式:指针表示
	int j=*(*(a+2)+3);
	printf("j=%d\n",j);
}

时间: 2024-10-14 13:37:13

二维数组的认识及其表示元素的两种方式的相关文章

C++从array数组向vector向量复制元素的两种方式

#include <iostream> #include <vector> using namespace std; int main() { const int arr_size = 5; int arr[arr_size] = {1,2,3,4,5}; // 第一种方式 vector<int> vec(arr, arr+arr_size); // 从array数组向vector向量复制元素 for (int i=0; i<vec.size(); i++) {

实现对多维数组按照某个键值排序的两种方法(array_multisort和array_sort)

实现对多维数组按照某个键值排序的两种解决方法(array_multisort和array_sort): 第一种:array_multisort()函数对多个数组或多维数组进行排序. //对数组$hotcat按照count键值大小降序进行排序: $hotcat =array( array('1501'=>array('catid'=>'1546','catname'=>'续梦PHP 一级','count'=>'588')), array('1501'=>array('catid

java中byte数组与int类型的转换(两种方式)

java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法,我们都知道,在socket传输中,发送.者接收的数据都是 byte数组,但是int类型是4个byte组成的,如何把一个整形int转换成byte数组,同时如何把一个长度为4的byte数组转换为int类型.下面有两种方式. 方法一 /** * int到byte[] * @param i * @return */ public static byte[] intToByteArray(int i) { byte[] resu

【转】java中byte数组与int类型的转换(两种方式)----不错

原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法,我们都知道,在socket传输中,发送.者接收的数据都是 byte数组,但是int类型是4个byte组成的,如何把一个整形int转换成byte数组,同时如何把一个长度为4的byte数组转换为int类型.下面有两种方式. 第一种方法: public static byte[] int2byte(int

java的取出map里所有元素的两种方式

/* * 取出map元素的两种方式 */package com.map.test; import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set; public class Test1 { public static void main(String[] args) { // TODO 自动生成的方法存根 Map<Integer,String> mp=new HashMa

将一个二维数组的行和列的元素互换,存到另一个二维数组中。

#include<stdio.h> int main() { int a[][3]={{1,2,3},{4,5,6},{6,9,7}};     int b[3][3],i,j;       printf("array a:\n");   for(i=0;i<=2;i++)       //处理数组中的一行中的各元素   {      for(j=0;j<=2;j++)     //处理a中的某一列的元素   {    printf("%5d"

二维数组可以输出-1号元素

#include<stdio.h>#include<string.h>int main(){ int arr[2][13]; memset(arr,0,sizeof(arr)); for(int i=0;i<10;i++) printf("%d ",arr[1][i]); printf("\n"); printf("%d",arr[1][-1]); return 0;} 输出 0:

二维数组作为函数参数传递剖析

前言 很多文章不外乎告诉你下面这几种标准的形式,你如果按照它们来用,准没错: //对于一个2行13列int元素的二维数组 //函数f的形参形式 f(int daytab[2][13]) {...} //以下两种可以忽略行数 f(int daytab[][13]) {...} f(int (*daytab)[13]) {...} 甚至会有人告诉你多维数组作为参数传递可以省略第一维,其他维不能省略.然而你对这种形式并不满意:如果事先限定了二维数组的大小,函数的泛用性就要大打折扣了.因为你真正需要的,

参数传递二维数组

转自http://blog.csdn.net/yunyun1886358/article/details/5659851 数组名作为形参 1 void func1(int iArray[][10]) 2 { 3 4 } 5 6 7 8 int main() 9 { 10 int array[10][10]; 11 func1(array); 12 13 } 编译通过,注意形参声明一定要给出第二个维度的大小,要不编译不过. 一维数组指针作为形参 1 void func2(int (*pArray)