c指針參數常見錯誤

參數的地址是能夠修改的,修改後的地址是不可能傳回給調用處的指針變量。也就是說,能夠修改參數地址所指的單元的值,這是能夠傳回到調用處的變量裏面的。

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

int subFunc(int arr[3]);

//交換兩整數
void change(int *data1, int *data2) {
    int *temp;

    //交換兩數的地址
    temp = data1;
    data1 = data2;    //修改參數1的地址
    data2 = temp;     //修改參數2的地址

    //交換後的地址在函數內沒問題,但不能傳回主程序
    printf("change:data1=%d, data2=%d\n", *data1, *data2);

    return ;
}

//動態得到內存                             //|  //改成以下內容即可以傳回主程序
void getMemory(int size, char *str) {      //|  char *getMemory(int size) {
    //動態分配的內存地址賦給str            //|
    str = (char *)malloc(size);            //|      return (char *)malloc(size);
                                           //|
    return ;                               //|  }
}                                          //|
                                           //|  //主程序的調用也得改爲: p = getMemory(40) ;
int main(void)
{
    int x = 25, y = 87 ;

    change(&x, &y);
    printf("main:x=%d, y=%d\n", x, y);    //x,y未獲得交換

    getMemory(40, p);    //p未獲得內存
    strcpy(p, "這是小雅的C語言教程");    //這句有錯,註釋以後才能獲得上圖結果
    free(p) ;

    return 0;
}

2、用局部變量的地址做返回值
這是初學者常犯的錯誤。小雅在開始作這個例子時,沒有用數組,而是用整型變量,結果令我大吃一驚,無論怎麼試,結果全是正確的。可小雅明明知道這程序是有毛病的,爲何不出錯呢?任何事都經不起琢磨,終於明白了其中的緣由,但在這兒不能說,不是小雅賣關子,是由於說了反讓初學者糊塗。

#include <stdio.h>

int *setData(void) {
    int arr[3] ;  //|   static int arr[3] ;

    arr[0] = 10 ;
    arr[1] = 35 ;
    arr[2] = 48 ;

    return arr ;  //局部變量隨函數結束而消亡,所以,返回以後是不正確的
}

int main(void)
{
    int i ;
    int *rst ;

    rst = setData();
    for (i=0; i<3; i++) {
        printf("%3d\n", rst[i]);
    }

    return 0;
}
上面的錯誤是將消亡的地址返回,修正的方法能夠考慮2種,一是將函數中的數組改成靜態的。另外一種辦法是再動態申請內存。這樣修改以後當然正確,但若是主程序中的rst改成數組,結果又怎樣呢?這將致使編譯錯誤。由於數組的地址不能被修改。
3、雙重指針做參數
上面第一個例子講到,不能把指針的地址傳給調用處的變量,但實際編程時的確有這種需求,但願調用一個函數,使得原來的空指針變成有數據內容的指針。
這其實不難實現,你們只要比較一下之前講到的基本類型(譬如int)做參數時,不能經過參數返回內容,咱們就改爲「int *」這樣的指針類型做參數,從而解決這個問題。如今咱們只要用雙重指針便一樣能夠解決指針的地址傳送的問題。但要注意:「int *」做參數,調用時用「&變量」;「int **」做參數,調用時用「&指針變量」。

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

void setData(int **ptr) {
    int *p = (int *)malloc(3 * sizeof(int));

    p[0] = 10, p[1] = 35, p[2] = 48 ;
    *ptr = p;  //注意:是將申請的內存地址賦給*ptr

    return ;
}

int main(void)
{
    int i ;
    int *data = NULL ;

    //這句有錯,應該用指針變量data的地址做參數
    setData(data);  //|   setData(&data);

    for (i=0; i<3; i++) {
        printf("%3d\n", data[i]);
    }

    return 0;
}
相關文章
相關標籤/搜索