一維數組和二維數組的運算(sizeof與strlen的區別)

在數組運算前,先了解一下數組的解引用到底是怎麼回事。

#include <windows.h>
#include <stdio.h>
int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,0};
	printf("%d\n", *arr);
	system("pause");
	return 0;
}


這段代碼輸出來的是什麼呢?




由此可見,數組的數組名其實是數組首元素的地址。

那麼,如果要訪問一個數組中其他元素呢?

#include <stdio.h>
int main()
{
	int arr[10] = {0};
	int i = 0;
	for(i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)
	{	
		printf("&arr[%d] = %p\n", i, &arr[i]);
		printf("%p\n", arr+i);
	}
	return 0;
}

這裏輸出的是&arr[i]的地址,那麼從arr[0]到arr[9]的地址能不能通過arr+i的方式打印出來呢?我們來看


                    


觀察結果我們發現,通過對數組名+整數的運算,其實可以獲取到數組每個人元素的地址。這樣我們就可以用指針訪問我們的數組了。


看完一維數組的表示方式,下列關於數組的一些運算我們必須掌握。


//一維數組


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


printf("%d\n",sizeof(a));  //16    數組的大小(4個元素,一個佔4個字節)


printf("%d\n",sizeof(a+0));  //4   第一個元素的大小


printf("%d\n",sizeof(*a));  //4    數組的解引用,數組首元素的大小(int型)


printf("%d\n",sizeof(a+1));  //4   第二個元素的大小


printf("%d\n",sizeof(a[1]));  //4  第二個元素的大小


printf("%d\n",sizeof(&a));  //4    數組的地址大小都是4


printf("%d\n",sizeof(&a+1)); //4   這個數組的下一個數組的地址


printf("%d\n",sizeof(&a[0])); //4  首元素的地址


printf("%d\n",sizeof(&a[0]+1)); //4  第二個元素的地址




//字符數組


char arr[] = {'a','b','c','d','e','f'};

printf("%d\n", sizeof(arr));  //6      數組的大小(6個元素,一個佔1個字節)


printf("%d\n", sizeof(arr+0));//4      首元素的地址


printf("%d\n", sizeof(*arr)); //1   數組的解引用,首元素的大(char型)


printf("%d\n", sizeof(arr[1]));//1   第二個元素的大小


printf("%d\n", sizeof(&arr)); //4   數組的地址是4


printf("%d\n", sizeof(&arr+1));//4   下個數組的首地址


printf("%d\n", sizeof(&arr[0]+1));//4  第二個元素的地址



printf("%d\n", strlen(arr)); //隨機


printf("%d\n", strlen(arr+0));//隨機
/*
printf("%d\n", strlen(*arr));//error
*/
/*printf("%d\n", strlen(arr[1]));*/ //error


printf("%d\n", strlen(&arr));//隨機


printf("%d\n", strlen(&arr+1));//隨機


printf("%d\n", strlen(&arr[0]+1));//隨機




爲什麼在運算strlen 時會出現這麼多隨機數呢?不妨先來看看strlen的用法


它從內存的某個位置(可以是字符串開頭,中間某個位置,甚至是某個不確定的內存區域)開始掃描,直到碰到第一個字符串結束符'\0'爲止



而對於strlen(*arr),在對arr解引用求長度時,會自動將首元素的地址先用ASCII碼值表示出了,然後向後查找,系統會一直查找下去(a的ASCII爲97)




strlen(&arr)是對arr的地址求長度,而arr的地址裏沒'\n',所以他會一直找到'\n'才能停下了,會產生一個隨機值



          

char *p = "abcdef";

printf("%d\n", sizeof(p)); //4    首元素的地址


printf("%d\n", sizeof(p+1));//4   第二個元素的地址


printf("%d\n", sizeof(*p));//1   首元素的大小


printf("%d\n", sizeof(p[0]));//1   首元素的大小


printf("%d\n", sizeof(&p));//4     指針的地址爲4


printf("%d\n", sizeof(&p+1));//4 下個指針的地址


printf("%d\n", sizeof(&p[0]+1));//4 第二個元素的地址



printf("%d\n", strlen(p));//6 求整個數組的長度

printf("%d\n", strlen(p+1));//5      從第二個元素開始的長度

/**printf("%d\n", strlen(*p));//error  

printf("%d\n", strlen(p[0]));*///error

printf("%d\n", strlen(&p));//x 從首元素地址開始找'\n',隨機值

printf("%d\n", strlen(&p+1));//x 同上

printf("%d\n", strlen(&p[0]+1));//5第二個元素開始的長度


 

這裏產生的錯誤和上面的strlen 一樣會從首元素對應的ASCII值出查找,所以一樣會出錯。


//二維數組

int a[3][4] = {0};


printf("%d\n",sizeof(a));//48 整個數組的大小


printf("%d\n",sizeof(a[0][0]));// 4 第一個元素的大小


printf("%d\n",sizeof(a[0]));//16 第一行元素的大小(int型)


printf("%d\n",sizeof(a[0]+1));//4 第一行的第二個元素的大小


printf("%d\n",sizeof(a+1));//4 第二個元素的地址


printf("%d\n",sizeof(&a[0]+1));//4 第一行第二個元素的地址


printf("%d\n",sizeof(*a));//16 數組首元素(相當於第一行的大小)


printf("%d\n",sizeof(a[3]));//16 下個數組的首個元素(第一行)大小



接下來總結一下sizeof和strlen的區別:

sizeof:

1、sizeof的單位是字節

2、sizeof(數組名)表示整個數組的大小(和類型有關)

3、sizeof(&數組名)表示整個數組的地址(和類型無關)

4、sizeof(*數組名)表示數組首元素的大小

strlen:

1、strlen(數組名)表示數組的長度(如果是非字符串則會產生一個隨機值)

2、strlen(*數組名)表示從首元素對應的ASCII開始找'\n',會出錯

3、strlen(&數組名)表示從首元素的地址開始找'\n',直到找到'\n',會產生一個隨機值

   結果和你想的一樣嗎?


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章