在數組運算前,先了解一下數組的解引用到底是怎麼回事。
#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',會產生一個隨機值
結果和你想的一樣嗎?