1. 程式人生 > >陣列維度以及陣列名作為右值

陣列維度以及陣列名作為右值

一.使用一級指標、一層迴圈遍歷一維陣列

這個不必多言,此時的陣列名即為一級指標常量。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
	int arr1[5] = { 1, 2, 3, 4, 5 };
	int arr2[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
	
        int *p1 = arr1;
	
        for (int i = 0; i < 5; i++)
	{
		printf("%d\n", p1[i]);
	}
	system("pause");
	return 0;
}

二.使用二級指標、一層迴圈遍歷二維陣列

顯然,此時的陣列名作為右值,代表的僅僅是一個地址編號,無有陣列地址(首地址)、首元素地址之分。

所以此時的二級指標是多餘的,地址+1的跨度即可訪問到下一個元素。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
	int arr1[5] = { 1, 2, 3, 4, 5 };
	int arr2[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
	
	int **p2 = arr2;
	
	for (int i = 0; i < 12; i++)
	{
		printf("%d\n", p2[i]);
	}
	system("pause");
	return 0;
}

三.使用二級指標、兩層迴圈遍歷二維陣列:顯然,這是錯誤的。

正如上面所說,地址名作為右值時僅僅代表一個地址編號,無有陣列地址(首地址)、首元素地址之分,所以自無跨度為一個一維陣列可言。

p為陣列首元素地址,*p就是首元素的值(*(p + 0)或p[0]),**p就是把首元素的值當成地址進行進階定址操作,顯然這是個野指標,操作即為非法的。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
	int arr1[5] = { 1, 2, 3, 4, 5 };
	int arr2[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
	
	int **p2 = arr2;
	
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			printf("%d\n", p2[i][j]);
		}
	}
	system("pause");
	return 0;
}

四.使用陣列指標、兩層迴圈遍歷二維陣列

陣列變數的本質還是指標,具有指標的特點:

1.它的跨度是由它指向的型別決定的:p3 ---> int[4],所以跨度為16。

2.它本身的型別是:p3 ---> int(*)[5]

3.*p3則為首元素地址,即一位陣列陣列首地址。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
	int arr1[5] = { 1, 2, 3, 4, 5 };
	int arr2[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
	
	int(*p3)[4] = arr2;
	
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			printf("%d\n", p3[i][j]);
		}
	}
	system("pause");
	return 0;
}

五.使用結構體指標、一層迴圈遍歷一維陣列

p是指向整個陣列的,*p則是首元素地址,即此時*p等價於arr或&p[0]。

無論是&arr還是arr,p都把這個地址當做一個int[4]的首地址。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
	int arr1[5] = { 1, 2, 3, 4, 5 };
	int arr2[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
	
	int(*p4)[5] = arr1;
	
	for (int i = 0; i < 5; i++)
	{
		printf("%d\n", p4[0][i]);
	}
	system("pause");
	return 0;
}

六.使用指標陣列、雙層迴圈,構建並遍歷二維陣列

arr先與[5]結合,表示它是一個有五個元素的陣列;再與*結合,表示陣列中的每個元素都是指標型別,這時候,我們就可以使用下標來訪問陣列中的每一個元素了,當然這也是由*()來實現的。

正因為如此,才構建出一個二維陣列。

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

int main(int argc, char *argv[])
{
	int a[5] = { 1 ,2 ,3, 4, 5 };
	int b[5] = { 6, 7, 8, 9, 10 };
	int c[5] = { 11 ,12 ,13, 14, 15 };
	
	//**(arr + 0)--->a[0]:這樣書寫更容易看出其值與int是是等價的。
	int *arr[3] = { a, b, c };

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			printf("%d\n", arr[i][j]);
		}
	}

	system("pause");
	return 0;
}


總結:

指標陣列使用的相對較少,一般用於二維陣列傳參。而二維陣列傳參還可以陣列元素地址,因為多維陣列在記憶體中都是一維的。