1. 大量的sizeof()和strlen()練習,加深理解數組和指針
1.1)一維數組
int main(int argc, const char * argv[])
{
// 一維數組
int a[] = {1,2,3,4};
printf("----------\n");
printf("%p\t->\ta[0]\t->\t%d\n", &a[0], a[0]);
printf("%p\t->\ta[1]\t->\t%d\n", &a[1], a[1]);
printf("%p\t->\ta[2]\t->\t%d\n", &a[2], a[2]);
printf("%p\t->\ta[3]\t->\t%d\n", &a[3], a[3]);
printf("----------\n");
printf("sizeof(a)\t->\t%lu\n", sizeof(a));//a代表整個數組,16
printf("sizeof(a+0)\t->\t%lu\n", sizeof(a+0));//a+0代表的是數組首元素的地址,&a[0],這裏32位輸出4,64位輸出8。
// printf("a+0\t->\t%p\n", a + 0);
// printf("a\t->\t%p\n", a);
printf("sizeof(*a)\t->\t%lu\n", sizeof(*a));//*a是數組第一個元素,4
// printf("*a\t->\t%d\n", *a);
printf("sizeof(a+1)\t->\t%lu\n", sizeof(a+1));//a+1代表數組第二個元素的地址,&a[1],8
// printf("%p\n", a+1);
printf("sizeof(a[1])\t->\t%lu\n", sizeof(a[1]));//a[1]的大小,4
printf("sizeof(&a)\t->\t%lu\n", sizeof(&a));//數組的地址,8
// printf("%p\n", &a);
printf("sizeof(*&a)\t->\t%lu\n", sizeof(*&a));//*和&抵消,相當於a代表整個數組,16
printf("sizeof(&a+1)\t->\t%lu\n", sizeof(&a+1));//這個是個地址,跨過了16個字節,8
// printf("%p\n", &a+1);
printf("sizeof(&a[0])\t->\t%lu\n", sizeof(&a[0]));//8
printf("sizeof(&a[0]+1\t->\t%lu\n", sizeof(&a[0]+1));//&a[1]
// printf("%p\n", &a[0]+1);
return 0;
}
1.2)字符數組
int main()
{
char a[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("----------\n");
printf("%p\t->\ta[0]\t->%c\n", &a[0], a[0]);
printf("%p\t->\ta[1]\t->%c\n", &a[1], a[1]);
printf("%p\t->\ta[2]\t->%c\n", &a[2], a[2]);
printf("%p\t->\ta[3]\t->%c\n", &a[3], a[3]);
printf("%p\t->\ta[4]\t->%c\n", &a[4], a[4]);
printf("%p\t->\ta[5]\t->%c\n", &a[5], a[5]);
printf("----------\n");
printf("sizeof(a)\t->\t%d\n", sizeof(a));//a表示整個數組,6
printf("sizeof(a+0)\t->\t%d\n", sizeof(a+0));//表示&a[0],8
// printf("%p\n", a+0);
printf("sizeof(*a)\t->\t%d\n", sizeof(*a));//*a表示a[0],1
// printf("%c\n", *a);
printf("sizeof(a[1])\t->\t%d\n", sizeof(a[1]));//a[1],1
printf("sizeof(&a)\t->\t%d\n", sizeof(&a));//數組的地址,8
// printf("%p\n", &a);
printf("sizeof(&a+1)\t->\t%d\n", sizeof(&a+1));//字符f(a[5])後面的那個元素的地址,跨越了一個a的長度,8
// printf("%p\n", &a+1);
printf("sizeof(&a[0]+1)\t->\t%d\n", sizeof(&a[0]+1));//字符b的地址,8
// printf("%c\n", *(&a[0]+1));
printf("----------------\n");
printf("strlen(a)\t->\t%d\n", strlen(a));//這個不確定是多少,strlen是以\0爲標誌計算的,不知道a數組完後是否爲'\0'
printf("strlen(a+0)\t->\t%d\n", strlen(a+0));
// printf("strlen(*a)\t->\t%d\n", strlen(*a));//ERROR!strlen()的參數類型爲char*的
// printf("strlen(a[1])\t->\t%d\n", strlen(a[1]));//ERROR!strlen()的參數類型爲char*的,做如下行的修改
printf("strlen(a[1])\t->\t%d\n", strlen(&a[1]));//OK
printf("strlen(&a)\t->\t%d\n", strlen(&a));//6
printf("strlen(&a+1)\t->\t%d\n", strlen(&a+1));//這個是不確定的
printf("strlen(&a[0]+1)\t->\t%d\n", strlen(&a[0]+1));//5
return 0;
}
1.3)字符串數組
int main()
{
char a[] = "abcdef";
printf("----------\n");
printf("%p\t->\ta[0]\t->%c\n", &a[0], a[0]);
printf("%p\t->\ta[1]\t->%c\n", &a[1], a[1]);
printf("%p\t->\ta[2]\t->%c\n", &a[2], a[2]);
printf("%p\t->\ta[3]\t->%c\n", &a[3], a[3]);
printf("%p\t->\ta[4]\t->%c\n", &a[4], a[4]);
printf("%p\t->\ta[5]\t->%c\n", &a[5], a[5]);
printf("----------\n");
printf("sizeof(a)\t->\t%d\n", sizeof(a));//7,字符數組長度,算\0
printf("sizeof(a+0)\t->\t%d\n", sizeof(a+0));//8,第一個元素的地址
printf("sizeof(*a)\t->\t%d\n", sizeof(*a));//1,第一個元素的大小
printf("sizeof(a[1])\t->\t%d\n", sizeof(a[1]));//1
printf("sizeof(&a)\t->\t%d\n", sizeof(&a));//8,地址
printf("sizeof(&a+1)\t->\t%d\n", sizeof(&a+1));//8,地址(是'\0'後面的那個字符的地址)
printf("sizeof(&a[0]+1)\t->\t%d\n", sizeof(&a[0]+1));//8,是a[1]的地址
printf("----------------\n");
printf("strlen(a)\t->\t%d\n", strlen(a));//6,字符串長度,不算\0
printf("strlen(a+0)\t->\t%d\n", strlen(a+0));//6
// printf("strlen(*a)\t->\t%d\n", strlen(*a));//ERROR!
// printf("strlen(a[1])\t->\t%d\n", strlen(a[1]));//ERROR!
printf("strlen(&a[1])\t->\t%d\n", strlen(&a[1]));//5
printf("strlen(&a)\t->\t%d\n", strlen(&a));//6
printf("strlen(&a+1)\t->\t%d\n", strlen(&a+1));//0
printf("strlen(&a[0]+1)\t->\t%d\n", strlen(&a[0]+1));//5
return 0;
}
1.4)字符串常量
int main()
{
char *p = "abcdef";
printf("--------\n");
printf("%p -> p[0] -> %c\n", &p[0], p[0]);
printf("%p -> p[1] -> %c\n", &p[1], p[1]);
printf("%p -> p[2] -> %c\n", &p[2], p[2]);
printf("%p -> p[3] -> %c\n", &p[3], p[3]);
printf("%p -> p[4] -> %c\n", &p[4], p[4]);
printf("%p -> p[5] -> %c\n", &p[5], p[5]);
printf("--------\n");
printf("%d\n", sizeof(p));//8,字符常量的地址
printf("%d\n", sizeof(p+1));//8,b字符的地址地址
// printf("%c\n", *(p+1));
printf("%d\n", sizeof(*p));//1,首元素的大小
printf("%d\n", sizeof(p[0]));//1,首元素的大小
printf("%d\n", sizeof(&p));//8,字符常量的地址
printf("%d\n", sizeof(&p+1));//8,這個並不是字符b的地址,是\0後面元素的地址
printf("%d\n", sizeof(&p[0]+1));//8,字符b的地址大小
printf("---------\n");
printf("%d\n", strlen(p));//6,字符串長度
printf("%d\n", strlen(p+1));//5,從b開始往後數字符串的長度
// printf("%d\n", strlen(*p));//ERROR!需要傳入一個char *
// printf("%d\n", strlen(p[0]));//ERROR!和上面一樣
printf("%d\n", strlen(&p));//這個值是不確定的,p不是數組,傳入後會從p的地址往後一個字節一個字節的找,遇到\0停下
printf("%d\n", strlen(&p+1));//不確定
printf("%d\n", strlen(&p[0]+1));//5,從字符b開始往後數
return 0;
}
1.5)二維數組
int main()
{
int a[3][4] = {0};
printf("-------\n");
printf("%p -> a[0][0] -> %d\n", &a[0][0], a[0][0]);
printf("%p -> a[3][4] -> %d\n", &a[3][4], a[3][4]);
printf("&a[3][4] - &a[0][0] = %d\n", &a[3][4]-&a[0][0]);//一共有多少個元素
printf("3 行 4 列\n");
printf("-------\n");
printf("%d\n", sizeof(a));//48,16個元素,每個元素佔4個字節
printf("%d\n", sizeof(a[0][0]));//4,第一個元素的大小
printf("%d\n", sizeof(a[0]));//16,第一行元素的大小
printf("%d\n", sizeof(a[0]+1));//8,a[0]是數組名,+1即爲下一個元素的地址,a[0]+1 <=> a[0][1]
// printf("%p\n", a[0]+1);
printf("%d\n", sizeof(*(a[0]+1)));//4,a[0][1]的大小(int)
printf("%d\n", sizeof(a+1));//8,第二個元素的地址,即&a[1]
printf("%d\n", sizeof(*(a+1)));//16,第二行元素,相當於sizeof(a[1])
printf("%d\n", sizeof(&a[0]+1));//8,第二行數組的地址,相當於a+1
printf("%d\n", sizeof(*(&a[0]+1)));//16,相當於a[1]
printf("%d\n", sizeof(*a));//16,相當於a[0]
printf("%d\n", sizeof(a[3]));//16,雖然越界了,但是還是當前數組的類型
return 0;
}
2. 練習題
未完待續~