c語言--指針

1.什麼是地址: 我們說變量都有自己的地址, 計算機要找到某個變量,必須知道該變量的地址.我們可以通過 & 獲得變量地址

取地址符 : &  通過取地址符就能把變量的地址給取出來.

int main(int argc, const char * argv[])
{
    int a;
    printf("%p\n", &a);//輸出變量a的地址
    return 0;
}

 

2.什麼是指針?

假如我們擁有很多客戶的地址, 那麼我們需要一個通訊錄來保存這些客戶的地址, 同樣對於計算機來說, 也需要用一個工具來保存變量的地址, 那麼這個工具,就是指針

指針就是用來保存內存地址的變量,本質是變量,變量存放的是地址,指針變量同樣具有變量名,變量類型,變量值

我們可以通過圖形來表示

指針定義:

一般形式: 類型 * 標示符

標示符: 表示指針變量的名字

類型: 表示指針指向的數據類型

 

int main(int argc, const char *argv[])
{
    int a;
    int *p;// 定義一個指針類型的變量p
    p= &a;//取出a的地址賦值給指針p
    printf("%p\n", p);
    printf("%p\n", &a);
    return  0;
}

 

3.間接尋址符: *

通過指針進行讀取

如果知道圖書館的地址, 那麼我們可以找到圖書館,並在圖書館內閱覽;

同理, 如果指針p保存了變量a的地址, 那麼就可以通過指針p來找到變量a, 並讀取變量a 的值

通過指針進行修改

只要知道某一個人的地址, 那麼我們就能找到這個人

同理, 知道變量的地址,那麼我們就能修改變量的值

 

/*
int main(int argc, const char *argv[])
{
    int a= 10;
    int *p= &a;
    printf("a== %d\n", *p);
    return  0;
}
*/

int main(int argc, const char *argv[])
{
    int a= 10;
    int *p= &a;//取出地址並賦值
    *p = 20;//修改變量a的值
    printf("a == %d", a);
    return  0;
}

 4.void * 指針

#define NULL ((void *) 0)

空指針 NULL  #define NULL ((void *)0)

指針就是用來保存內存地址的變量, 因此定義一個指針後一定要用它來保存一個內存地址, 假如不那麼做, 那麼該指針就是一個野指針, 它的默認值是隨機的, 因此會造成混亂

int main(int argc, const char *argv[])
{
    int a = 10;
    char ch = 'a';
    void *p=&a;
    void *q = &ch;
    //  *p = 10;
    printf("%d\n", *(int *)p);
    printf("%c\n",*(char *)q);
    //printf("%d", *p);
    return  0;
}

 

5.野指針

(1)當一個指針指向內容非法時, 那這就是一個野指針

(2)定義一個指針沒有賦初值, 這個指針就是野指針

(3)一個指針指向的內容被銷燬了,這個指針就是野指針

 

int main(int argc, const char *argv[])
{
    int *p=NULL;//undefine
    *p = 10;
    printf("%d\n",*p);
    return 0;
}

 

 6.指針與函數

//指針變量作爲函數參數

//封裝一個函數交換兩個值
void swap(int a, int b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
    return ;
}
int main(int argc, const char *argv[])
{
    int a = 10;
    int b = 20;
    printf("交換前 a== %d b== %d\n", a, b);
    swap(a, b);
    printf("交換後 a== %d b== %d\n", a, b);
    return 0;
}

 問題:   

思考下爲什麼上面的函數值沒有交換過來呢

用什麼方法能夠解決這個問題呢?(值傳遞,址傳遞!)

 

//使用指針變量作爲參數
void swap(int *a , int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
    return ;
}

int main(int argc, const char *argv[])
{
    int a= 10, b= 20;
    printf("交換前 a== %d b== %d\n", a, b);
    //傳遞變量的地址
    swap(&a, &b);
    //結果交換過來了!
    printf("交換後 a== %d b== %d\n", a, b);
    return 0 ;
}

 

7.指針與數組

數組名就是數組的首元素地址,數組名是一個常量

//數組名就是數組的首元素地址,數組名是一個常量
/*int main(int argc, const char *argv[])
{
    int a[5]={1, 2, 3, 4, 5};
    printf("%p\n", a);
    printf("%p\n", &a);
    printf("%p\n", &a[0]);
    return  0;
}*/

int main(int argc, const char *argv[])
{
    int a[5]= {1, 2, 3, 4, 5};
    int *p=a;//數組地址賦值給指針變量p
    for (int i = 0; i<5; i++) {
       //輸出每一個元素
        printf("a[%d]==%d\n", i,*(p+i));
    }
    return  0;
}
//指針實現數組逆序

void func(int *a,int len)
{
    int i;
    int temp;
    for (i=0; i<len/2; i++) {
        //通過指針操作數組元素
        temp = *(a+i);
        *(a+i)=*(a+len-i-1);
        *(a+len-i-1)=temp;
    }
}

 

 

 實例:編寫一個對整型數組排序的函數

//選擇排序法
void sort(int *src, int len)
{
    int i, j, k,temp;
    for (i = 0; i< len -1; i++) {
        k = i;
        for (j= i+1; j<len; j++) {
            if(*(src+k) > *(src + j))
            {
                k = j;
            }
        }
        if (k!=i) {
           //通過指針操作數組元素
            temp = *(src+k);
            *(src+k)= *(src+i);
            *(src+i)= temp;
        }
    }
}

int main(int argc, const char *argv[])
{
    int a[5];
    printf("請輸入5個整型數據: \n");
    for (int i= 0; i< 5; i++) {
        scanf("%d", &a[i]);
    }
    //傳遞數組
    sort(a, 5);
    for (int i= 0; i< 5; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}

 

發佈了24 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章