由於做算法題都用的C語言,就找時間補習了一下指針,看的書是《指針的藝術》,作者是蔡明志,把書中的經典題拿出來做個筆記,做個備份

++和*具有相同的運算優先級,但結合性是由右至左的。

    int i[] = {10,20,30,40,50};
    int *pa[] = {i, i+2, i+1, i+4, i+3};
    int **p2 = pa;//**p2為10
    p2++;//**p2為30
    ++*p2;//**p2為40
    **p2++;//**p2為20
    ++**p2;//**p2為21

第一句註釋不解釋了。
第二句p2++是將p2右移一位,移到i+2,即30
第三句++*p2根據結合性可看做++(*p2),*p2是指向i+2(30)的指針,將地址向下移一位便到了40(i中的地址是連續的)
第四句**p2++根據結合性可以看做**(p2++),由於++在後面,執行順序又變成了(*(*p2)++),上面說過*p2指向i+2,右移一位是i+1,再取值為20
第五句++**p2根據結合性看做++(**p2),**p2為20,++後為21


    char *s[] = {"Stanford", "University", "California", "America"};
    char **sa[] = {s, s+1, s+2, s+3};
    char ***p3 = sa;
    printf("**p3++ = %s\n",**p3++);//Stanford
    printf("**++p3 = %s\n",**++p3);//California
    printf("**++*p3 = %c\n",**++*p3);//A
    printf("*(*--*++p3+3) = %c\n",*(*--*++p3+3));//i

可以看做是char s[4][10]
第一句**p3++++在後面,先執行**p3,就是Stanford,然後++,下移指向U
第二句**++p3,先++,下移指向C,輸出字符串California
第三句`
++p3,同第二句,也是將其下移,和第二句的區別是*是取元素的內容,*是指針,故第二句輸入的是字符串,第三句輸出的是字符 第四句(++p3+3)比較長,慢慢來分析,++p3下移指向A,++p3上移指向C,++p3+3此時已經有兩個,故+3是向右移3個位置,是指向i的指針,(++p3+3)3個*`則是取元素i


下面這個例子比較經典的展示了傳值調用和傳址調用的效果。。。

void swap_by_value(int a,int b) {
    int temp = a;
    a = b;
    b = temp;
}

void swap_by_address(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 100,y = 200;
    printf("before:x = %d,y = %d\n",x,y);//x = 100,y = 200;
    swap_by_value(x,y);
    printf("after:x = %d,y = %d\n",x,y);//x = 100,y = 200;

    x = 100; y = 200;
    printf("before:x = %d,y = %d\n",x,y);//x = 100,y = 200;
    swap_by_address(&x, &y);
    printf("after:x = %d,y = %d\n",x,y);//x = 200,y = 100;
}

下面這是一個改錯題

//n為5
int *pf(int x[5],int n) {
    int m;
    int k[5];
    int j[] = {1,2,3};
    for (m = 0; m < 5;m++) {
        k[m] = j[m]+ x[m];
    }
    return k;
}

此題的主要問題在int k[5]這句話應該放在函數外面,局部變量會被銷毀,變成野指針。。。


幾個容易混淆的:
int (*p)[11]:p是指向含有11個元素數組的指針
int *p[1]:p是數組,含有11個元素,每一元素均為指向int型的指針
int **p;p是一個二重指針,需經兩次的間接訪問才能得到整數變量值
int(*p)(int):p是指向函數的指針,此函數含有int參數,返回值的數據類型為int
int *p(int):p是函數,此函數有一個int型參數,並返回一個指向int的指針


//計算字符串長度(strlen)
int stringLength(char *) {
    int t = 0;
    while(*p != '\0') {
        t++;
        p++;
    }
}
//複製字符串(strcpy),需注意傳進來dest的內存夠不夠大
void myStringCopy(char *dest,char *source) {
    while((*dest = *source) != '\0') {
        source++;
        dest++;
    }
}
//拼接字符串(strcat),同樣需要注意傳進來的dest內存夠不夠大
void stringConcate(char *dest,char *source) {
    while(*dest != '\0') dest++;
    while((*dest = *source) != '\0') {
        source++;
        dest++;
    }
}
//拼接前n個字符到字符串(strncat),注意dest內存
void stringConcate_n(char *dest,char *source,int n) {
    int i = 1;
    while(*dest != '\0') dest++;
    while (i <= n && (*dest = source) != '\0') {
        source++;
        dest++;
        i++;
    }
}
//字符串比較(strcmp:0相等,1(正數)大於,-1(負數)小於)順便在此說明以下,判斷字符是否相等直接使用==即可,==表示判斷地址是否一樣,而不是內容,當然,地址一樣內容一定一樣,但內容一樣地址不一定是一樣的
int stringCompare(char *x,char *y) {
    for( ; *x == *y; x++,y++) {
        if (*x == '\0') return 0;
    }
    return *x - *y;
//比較字符串的前n位(strncmp)
int stringCompare_n(char *x,char *y, int n) {
    for (int i = 1; (*x == *y) || i <= n; x++,y++) {
        if (*x == '\0') return 0;
    }
    return *x - *y;
//關於結構體的指針(第一段)
struct student {
        char *name;
        int scrore;
    };

    struct student st = {"Brian",97};
    struct student *ptr = &st;

    printf("ptr->name = %s\n",ptr->name);//Brian
    printf("*ptr->name = %c\n",*ptr->name);//B
    printf("*ptr->name++ = %c\n",*ptr->name++);//B
    printf("*ptr->name = %c\n",*ptr->name);//r
    printf("*ptr->score = %d\n",ptr->scrore);//97
    printf("*ptr->score++ = %d\n",(ptr->scrore)++);//97
    printf("*ptr->sco = %d\n",ptr->scrore);//98
//關於結構體的指針(第二段)
struct student_new {
        char name[20];
        int scrore;
    };

    struct student_new st = {"Brian",97};
    struct student_new *ptr = &st;

    printf("*ptr->name = %c\n",++*(ptr->name));//C
    //在結構體中,如果是一般變量,則用.調用,若是指針變量,則用->調用,也可用*調用,如上例(*student).name

最後是鏈表,由於之前的算法題已經涉及過鏈表,我在這裏就不說了,這本書上介紹的也就是創建及增刪改查之類。

本書我只看了前8章,因為從第九章開始就講的是C++/C#/JAVA之類的,所以筆記就到這裏了。

版權聲明:本文為 Crazy Steven 原創出品,歡迎轉載,轉載時請註明出處!

分享