C語言中二維數組名與數組地址、首行地址、首行首元素地址理解

對應書籍解釋
在這裏插入圖片描述

案列

#include <stdio.h>

int main()
{
	int a[3][4] = {{100, 2, 3, 4}, {200, 2, 3, 4}, {3, 2, 3, 4}};
	// 0行0列首地址
	int *p = *a;
	int *p1 = *(a+0);
	int *p2 = a[0];
	printf("%d \n", *p);
	printf("%d \n", *p1);
	printf("%d \n", *p2);
	// 1行0列首地址
	int *q = a[1];
	int *q1 = *(a+1);
	printf("%d \n", *q);
	printf("%d \n", *q1);
	printf("%d \n", *p2);

	/* 首行表示法 */
	// 0行首地址a
	printf("%d %d \n", p, a);
	// 1行首地址
	printf("%d %d %d %d \n", q, a+1, &a[1], a[1]);

	// 2行1列值
	printf("%d %d %d \n", *(a[1] + 1), * (*(a+1) + 1), a[1][1]);

	return 0;
}

輸出

在這裏插入圖片描述

特殊關注

int main()
{
	int a[3][4] = {{100, 2, 3, 4}, {200, 2, 3, 4}, {3, 2, 3, 4}};

	// 1行0列首地址
	int *q = a[1];
	
	// 1行首地址
	printf("%d %d %d %d %d \n", q, a+1, *(a+1), &a[1], a[1]);

	return 0;
}

其中a+1=*(a+1), a[1]=&a[1]

爲了弄清楚這個差異,我們需要明白一種概念,數組行首地址和元素地址,
下面將通過例子說明

int a[3][4] = {{100, 2, 3, 4}, {200, 2, 3, 4}, {3, 2, 3, 4}};

其中二維數組a物理存儲如下,我們會把二維數組邏輯存儲爲二維表格
在這裏插入圖片描述

將二維數組作爲普通一維數組使用,也就是說指針往後移動是下一個元素的地址
在這裏插入圖片描述
給出一個示例

#include <stdio.h>

int main()
{
	int a[3][4] = {{100, 2, 3, 4}, {200, 2, 3, 4}, {3, 2, 3, 4}};

	// 0行0列首地址
	int *q = &a[0][0];
	for (int * temp = q; temp < q + 12; temp++)
	{
		if ((temp - q) % 4 == 0)
		{
			printf("\n");
		}
		printf("%-5d ", *temp);
	}
	printf("\n");
	
	return 0;
}

在這裏插入圖片描述

指向多個元素組成的一位數組指針,也就是說指針的移動是m個元素的距離,如下圖所示,如果是由4個元素組成的一位數組指針,當p+1時,指向的是下一個4個元素組成的一位數組起始地址
在這裏插入圖片描述
給出一個示例

#include <stdio.h>

int main()
{
	int a[3][4] = {{100, 2, 3, 4}, {200, 2, 3, 4}, {3, 2, 3, 4}};

	// 0行首地址
	int (*q)[4] = a;

	for (int (*temp)[4] = q; temp < q + 3; temp++)
	{
		// 由4個元素組成的一位數組構成的行指針,所有有四個元素
		for (int i = 0; i < 4; i++)
		{
			printf("%-5d ", (*temp)[i]);
		}
		printf("\n");
	}
	printf("\n");
	
	return 0;
}

在這裏插入圖片描述
通過這個例子我們可以明白行指針概念,也就是說可以移動n個元素的到第n個元素的地址。

現在來看這兩個爲什麼相等:a+1=*(a+1), &a[1]=a[1]

int a[3][4] = {{100, 2, 3, 4}, {200, 2, 3, 4}, {3, 2, 3, 4}};

其中a是0行首地址,也就是一維數組指針,包含4個元素,a+1指向的第四個元素後的地址,也就是1行首地址
在這裏插入圖片描述

a[0]或者*(a+0)或者*a(三者是相等的),則表示0行0列的地址,也就是說指針+1是下一個元素的地址,如圖所示a[0]a[0] + 1
在這裏插入圖片描述

也就是說,如果要輸出0行0列的值100,其中是a是0行首地址,需要先轉換成0行0列地址,然後再輸出值

a->*a->**a,其中a與*a相同

已經證明了問題:a+1=*(a+1), a[1]=&a[1]

  • a+1=*(a+1)
    a+1是1行首地址,通過1行首地址轉換爲1行0列地址,兩個地址相同,所以相等
  • a[1]=&a[1]
    a[1]是1行0列地址,通過1行0列地址轉換爲1行首地址,兩個地址相同,所以相等
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章