指針和數組的練習題解析

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. 練習題


未完待續~

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