C語言的靈魂——指針

C語言的靈魂—指針

指針是什麼

在計算機科學中,指針(Pointer)是編程語言中的一個對象,利用地址,它的值直接指向(points to)存在電腦存儲器中另外一個地方的值。因爲經過地址能找到所需的變量單元,能夠說,地址指向該變量單元。所以,將地址形象化的稱爲「指針」。總結來講,指針就是指向地址的變量!編程

指針的做用

c語言指針能夠有效地表示覆雜的數據結構、動態分配內存、高效地使用數組和字符串、使得調用函數時獲得多個返回值等。指針的應用每每與數組聯繫在一塊兒,是最頻繁的,也是最基礎的。參數傳遞時只須要拷貝地址值,提升程序的運行效率。有效的表示數據結構,能動態分配內存。數組

指針

指針的語法

指針變量的定義: 類型 * 指針變量名 &:表示取地址操做 *: 表示取地址中的值markdown

怎麼去理解指針

你們可能一時半會可能很難理解指針含義。咱們的計算機都會有一個內存,而且這個內存的每個部分有一個標記表示它的位置,這個標識就是咱們的地址,地址對應的區域存放的就是咱們的數據(值)。就像咱們住酒店,酒店是內存,門牌號是咱們的地址,住在房間裏的人就是咱們的數據!數據結構

代碼示例

#include<stdio.h>

int main(){
    int num = 10;
    double num2 = 10.0;
    int * p ;
    p = &num;

    //這種不一樣類型的變量以前的操做是不合法的
    // p = &num2;

    printf("p = %p\n",p);
    printf("num = %d\n",num);
    printf("*p = %d\n",*p);

    // num 和 p表明的是同一個地址的數據,
    // 當使用 *p 去修改數據的時候,num表明的數據也會改變!
    *p = 11;
    printf("p = %p\n",p);
    printf("num = %d\n",num);
    printf("*p = %d\n",*p);

    return 0;
}

/* 運行結果: p = 0x7ffee1eee7c8 num = 10 *p = 10 p = 0x7ffee1eee7c8 num = 11 *p = 11 */
複製代碼

經過以上代碼咱們不難理解:指針變量中,p 存放的是地址,*p 是取地址對應的值。num 變量直接存放地址對應的值!當咱們使用 *p 修改數據的時候,咱們 num 的存放的值也會發生改變!咱們使用 & 符號便可取出變量的地址 舉個例子,p 存放的是門牌號,*p 表明居住的客人,num 也是表明這個門牌號下居住的客人,當使用 *p 修改掉居住的人,num 也會發生相應的改變,由於他們表明的都是這個門牌號下居住的人。&num 即表明取出這個客人的房間門牌號編程語言

什麼是雙重(n重)指針

咱們根據以前的解釋能夠知道,每一個變量在內存中都有一個地址相對應。雙重指針實際上存放的全是地址。函數

代碼示例

#include<stdio.h>

int main(){
    int num = 10;
    int * p;
    p = &num;

    // 雙重指針
    int  ** q;

    // 指針變量也是變量的一種,即 p 也是有對應的地址
    // &p 即取 p 變量的地址
    q = &p;

    // p 變量存放的地址 ,即num變量的地址
    printf("p = %p\n",p);
    // p 變量自身的地址
    printf("p = %p\n",&p);
    // q 存放的地址就是 p 變量自身的地址
    printf("q = %p\n",q);
    // *p == num
    printf("*p = %d\n",*p);  
    // **q == *p == num
    printf("**q = %d\n",*p);

    return 0;
}

/* 執行結果: p = 0x7ffee910c7c8 p = 0x7ffee910c7c0 q = 0x7ffee910c7c0 *p = 10 **q = 10 */
複製代碼

圖解

graph LR
    q --> p
    p --> num

n重指針

n重指針同理學習


數組實際上使用的就是指針,咱們再學習下數組類型ui

指針函數和函數指針

指針函數

顧名思義,指針函數就是返回值爲指針的函數spa

語法示例

#include <stdio.h>

int *fun(int a, int b, int *p) {
    *p = a + b;
    return p;
}
int main() {
    int *p;
    p = fun(10, 10, p);
    printf("%d \n", *p);
    return 0;
}
/* 執行結果: 20 */
複製代碼

函數指針

函數指針就是指向函數的指針。一個函數標識符就表示了它的地址指針

示例代碼

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int sub(int a, int b) {
    return a - b;
}

int (*fun)(int a, int b);

int main() {
    // 函數指針用法一
    fun = add;
    //調用方法二
    printf("%d \n", fun(10, 10));

    //用法二
    fun = &sub;
    //調用方法一
    printf("%d \n", (*fun)(10, 10));
    return 0;
}
/* 執行結果: 20 0 */
複製代碼

一維數組

語法規則

類型名 變量名 [數組大小] 字符串數組:C語言中一個字符串的界定範圍是 '\0',當遇到'\0'時認爲字符串已經結束

語法示例

#include<stdio.h>

int main(){
    char chs[100] = {'a','b','c','\0'};
    printf("chs = %s\n",chs);

    //指針版示例
    printf("point verion:\n");
    printf("chs = ");
    for(int i = 0; *(chs + i) != '\0';i ++){
        printf("%c",*(chs + i));
    }
    printf("\n");
    return 0;
}

/* 運行結果: chs = abc point verion: chs = abc */
複製代碼

咱們從示例代碼中能夠看到: chs[i] 等價於 * (chs + i)

二位數組

語法定義

類型名 數組變量名稱 [行數][列數]

代碼示例

#include <stdio.h>

int main() {

    //未初始化的數組其值是不肯定的
    int arr[7][7] = {0};

    //輸入行數
    printf("%lu\n", sizeof(arr) / sizeof(arr[0]));

    //輸出列數
    printf("%lu\n", sizeof(arr[0]) / sizeof(int));

    //打印數組信息 數組實際上就是二維指針
    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
    {
        for (int j = 0; j < sizeof(arr[0]) / sizeof(int); j++)
        {
            printf("%d ", (*(arr + i) + j));
        }
        printf("\n");
    }

    // 打印數組的地址信息 能夠看到,數組其實是一塊連續的地址空間
    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)  
    {
        for (int j = 0; j < sizeof(arr[0]) / sizeof(int); j++)
        {
            printf("%p ", (*(arr + i) + j));
        }
        printf("\n");
    }
    return 0;
}

/* 執行結果: 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x7ffee5a9d700 0x7ffee5a9d704 0x7ffee5a9d708 0x7ffee5a9d70c 0x7ffee5a9d710 0x7ffee5a9d714 0x7ffee5a9d718 0x7ffee5a9d71c 0x7ffee5a9d720 0x7ffee5a9d724 0x7ffee5a9d728 0x7ffee5a9d72c 0x7ffee5a9d730 0x7ffee5a9d734 0x7ffee5a9d738 0x7ffee5a9d73c 0x7ffee5a9d740 0x7ffee5a9d744 0x7ffee5a9d748 0x7ffee5a9d74c 0x7ffee5a9d750 0x7ffee5a9d754 0x7ffee5a9d758 0x7ffee5a9d75c 0x7ffee5a9d760 0x7ffee5a9d764 0x7ffee5a9d768 0x7ffee5a9d76c 0x7ffee5a9d770 0x7ffee5a9d774 0x7ffee5a9d778 0x7ffee5a9d77c 0x7ffee5a9d780 0x7ffee5a9d784 0x7ffee5a9d788 0x7ffee5a9d78c 0x7ffee5a9d790 0x7ffee5a9d794 0x7ffee5a9d798 0x7ffee5a9d79c 0x7ffee5a9d7a0 0x7ffee5a9d7a4 0x7ffee5a9d7a8 0x7ffee5a9d7ac 0x7ffee5a9d7b0 0x7ffee5a9d7b4 0x7ffee5a9d7b8 0x7ffee5a9d7bc 0x7ffee5a9d7c0 */
複製代碼

數組相關的函數

#include <stdio.h>
int main(){
    char old[100];
    char new[200];
    int n = 10;

    //字符數組操做函數
    //將舊數組的數據拷貝到的新的數組之中。舊數組的數據遇到了\0就中止複製。新數組的長度必須大於等於舊數組數據長度 + 1
    strcpy(new,old);

    // 將舊數組的前n位字符拷貝到新數組中。新數組的長度必須大於等於新數組原數據長度 + 舊數組數據長度 + 1
    strncpy(new,old,n);

    //兩個字符數組進行比較。首先從第一位開始逐位比較,按照字典序的大小進行比較。遇到第一個不等的字符或者遇到了\0中止比較。等於返回0,new < old返回 -1,new > old 返回 1
    strcmp(new,old);

    //將兩個字符串進行鏈接。新數組的長度必須大於等於 新數組的數據長度 + 舊數組的數據長度 + 1
    strcat(new,old);

    return 0;
}
複製代碼

以上就是本期的所有內容了,感謝你能看到這裏。咱們下期見!

相關文章
相關標籤/搜索