C語言指針數組和指向指針的指針

請先看下面的代碼:
#include <stdio.h>
#include <stdlib.h>

int main(){
    char *lines[5] = {
        "COSC1283/1284",
        "Programming",
        "Techniques",
        "is",
        "great fun"
    };

    char *str1 = lines[1];
    char *str2 = *(lines + 3);
    char c1 = *(*(lines + 4) + 6);
    char c2 = (*lines + 5)[5];
    char c3 = *lines[0] + 2;

    printf("str1 = %s\n", str1);
    printf("str2 = %s\n", str2);
    printf("  c1 = %c\n", c1);
    printf("  c2 = %c\n", c2);
    printf("  c3 = %c\n", c3);
    return EXIT_SUCCESS;
}

運行結果:
str1 = Programming
str2 = is
c1 = f
c2 = 2
c3 = E

爲了更加直觀,把上面的數組改成下面的形式:

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

int main(){
    char *string0 = "COSC1283/1284";
    char *string1 = "Programming";
    char *string2 = "Techniques";
    char *string3 = "is";
    char *string4 = "great fun";

    char *lines[5];
    lines[0] = string0;
    lines[1] = string1;
    lines[2] = string2;
    lines[3] = string3;
    lines[4] = string4;

    char *str1 = lines[1];
    char *str2 = *(lines + 3);
    char c1 = *(*(lines + 4) + 6);
    char c2 = (*lines + 5)[5];
    char c3 = *lines[0] + 2;

    printf("str1 = %s\n", str1);
    printf("str2 = %s\n", str2);
    printf("  c1 = %c\n", c1);
    printf("  c2 = %c\n", c2);
    printf("  c3 = %c\n", c3);
    return EXIT_SUCCESS;
}

這樣,或許會清晰很多,char *lines[5]; 定義了一個指針數組,數組的每一個元素都是指向char類型的指針。最後5行,爲數組的每一個元素賦值,都是直接賦給指針。

而lines,是一個指向指針的指針,它的類型爲 char **,所以 *lines 是一個指向字符的指針,**lines是一個具體的字符。這一點很重要,一定要明白。

指針是可以進行運算的,lines 爲lines[5]數組的首地址,即第0個元素的地址;lines+0, lines+1, lines+2 … 分別是第0, 1, 2 …個元素的首地址,(lines+0)或lines[0], (lines+1)或lines[1], *(lines+2)或lines[2] … 分別是字符串 str0, str1, str2 … 的首地址。所以:
lines == (lines+0) == lines[0] == str0
*(lines+1) == lines[1] == str1
*(lines+2) == lines[2] == str2

注意:lines爲指向指針的指針,所以(lines+n)爲指針,*(lines+n)才爲具體的字符。

分析上面的題目中:

  • lines[1]:它是一個指針,指向字符串string1,即string1的首地址。
  • *(lines + 3):lines + 3 爲lines[5]數組第3個元素的地址,*(lines + 3)爲第3個元素,它是一個指針,指向字符串string3。
  • *(*(lines + 4) + 6):*(lines + 4) + 6 == lines[4] + 6 == string4 + 6,爲字符串string4第6個字符的地址,即 f 的地址,*(*(lines + 4) + 6) 就表示字符 f。
  • ( *lines + 5 ) [5]:*lines + 5 爲字符串 string0 第5個字符的地址,即 2 的地址,(*lines + 5)[5]等價於*(*lines + 5 + 5),表示第10個字符,即2。
  • *lines[0] + 2:*lines[0] 爲字符串string0 第0個字符的地址,即C的地址。字符與整數運算,首先轉換爲該字符對應的ASCII碼值,然後再運算,所以 *lines[0] + 2 = 67 + 2 = 69。不過要求輸出字符,所以還要轉換成69所對應的字符,即E。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章