溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎樣理解C語言中的初階指針

發(fā)布時間:2021-10-09 09:14:15 來源:億速云 閱讀:132 作者:柒染 欄目:開發(fā)技術(shù)

本篇文章為大家展示了怎樣理解C語言中的初階指針,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

    1.指針是什么

    初學(xué)者都有一個疑問,那就是指針是什么?簡單的說,就是通過它能找到以它為地址的內(nèi)存單元。

    地址指向了一個確定的內(nèi)存空間,所以地址形象的被稱為指針。

    int main()
    {
    	int a = 10;
    	int* pa = &a;
        return 0;
    }
    //pa是用來存放地址(指針),所以pa是指針變量。

    總結(jié):指針就是變量,用來存放地址的變量。(存放在指針中的值都被當(dāng)成地址處理)。

    地址是唯一標(biāo)識一塊空間的。

    指針的大小在32位平臺是4個字節(jié),在64位平臺是8個字節(jié)。

    2.指針和指針類型

    我們知道變量有不同的類型(整型、浮點型、字符型等),其實指針也是有不同類型的。

    指針類型的意義1:
    指針類型決定了指針解引用操作的時候,一次訪問幾個字節(jié)(訪問內(nèi)存的大?。?br/>char* 指針解引用訪問1個字節(jié)
    int* 指針解引用訪問四個字節(jié)

    int main()
    {
    	char* pc = &a;
    	*pc = 0;
    	return 0;
    }

    指針類型的意義2:

    指針類型決定了,指針±整數(shù)的時候的步長(指針±整數(shù)的時候,跳過幾個字節(jié))

    int* 指針+1 跳過四個字節(jié)

    char* 指針+1 跳過一個字節(jié)

    int main()
    {
    	int a = 10;
    	int* pa = &a;
    	char* pc = &a;
    	printf("%p\n", pa);
    	printf("%p\n", pc);
    	printf("%p\n", pa+1);
    	printf("%p\n", pc+1);
    	return 0;
    }

    3.野指針

    野指針就是指針指向的位置是不可知的(隨機的、不正確的、沒有明確限制的)。

    3.1野指針成因

    1.指針未初始化

    int main()
    {
        int* p;//局部變量指針未初始化,默認(rèn)為隨機值
        *p = 20;//通過p中存的隨機值作為地址,找到一個空間,這個空間不屬于我們當(dāng)前的程序
        //就造成了非法訪問,p就是野指針
        return 0;
    }

    2.指針越界訪問

    int main()
    {
        int arr[10] = 0;
        int i = 0;
        int* p = arr;
        for(i =0; i <= 10; i++)
        {
            *p = i;
            p++;//當(dāng)指針指向的范圍超出數(shù)組arr的范圍時,p就是野指針
        }
        return 0;
    }

    3.指針指向的空間釋放

    int* test()
    {
        int a = 10;
        return &a;
    }
    int main()
    {
        int* p = test();
        printf("%d\n",*p);
        return 0;
    }

    3.2如何規(guī)避野指針

    1.指針初始化

    2.小心指針越界

    3.指針指向空間釋放即使置NULL

    4.避免返回局部變量的地址

    5.指針使用之前檢查有效性

    int main()
    {
        int a = 10;
        int* p = &a;//明確地初始化,確定指向
        int* p2 = NULL;//不知道一個指針當(dāng)前應(yīng)該指向哪里時,可以初始化為NULL
        return 0;
    }

    4.指針的運算

    4.1指針±整數(shù)

    #define N_VALUES 5
    float values[N_VALUES];
    float* vp;
    for(vp = &values[0]; vp < &values[N_VALUES];)
    {
        *vp++ = 0;
    }
    int main()
    {
        int arr[10] = {1,2,3,4,5,6,7,8,9,0};
        int* p = &arr[9];
        printf("%p\n",p);
        printf("%p\n",p-2);
        return 0;
    }

    4.2指針-指針

    指針-指針 得到的數(shù)字的絕對值是指針和指針之間元素的個數(shù)

    int main()
    {
    	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
    	printf("%d\n", &arr[9] - &arr[0]);
    	printf("%d\n", &arr[0] - &arr[9]);
    	return 0;
    }

    指針-指針 的前提是兩個指針指向同一塊區(qū)域

    int main()
    {
        int arr[10] = {1,2,3,4,5,6,7,8,9,0};
        char ch[5] = {0};
        printf("%d\n",&arr[9] - &ch[0]);//err
        return 0;
    }

    應(yīng)用 求字符串長度

    int my_strlen(char* s)
    {
    	int count = 0;
    	char* start = s;
    	while(*s!='\0')
    	{
    		s++;
    	}
    	return s - start;
    }
    int main()
    {
    	char arr[] = "abcdef";
    	int len = my_strlen(arr);
    	printf("%d\n", len);
    	return 0;
    }

    4.3指針的關(guān)系運算

    #define N_VALUES 5
    float values[N_VALUES];
    float *vp;
    for(vp = &values[N_VALUES]; vp > &values[0];)
    {
        *--vp = 0;
    }

    上述程序也可以寫成這樣

    for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
    {
        *vp = 0;
    }

    實際在絕大部分的編譯器上是可以順利完成任務(wù)的,然而我們還是應(yīng)該避免這么寫,因為標(biāo)準(zhǔn)并不保證它可行。

    標(biāo)準(zhǔn)規(guī)定

    允許指向數(shù)組元素的指針與指向數(shù)組最后一個元素后面的那個內(nèi)存位置的指針比較,但是不允許與指向第一個元素之前的那個內(nèi)存位置的指針進(jìn)行比較。

    5.指針和數(shù)組

    數(shù)組 - 是一塊連續(xù)的空間,放的是相同類型的元素

    數(shù)組大小和元素類型,元素個數(shù)有關(guān)系

    指針(變量) - 是一個變量,放地址

    指針變量的大小 是4(32bit)/8(64bit)個byte

    數(shù)組名確實是首元素地址

    但是有兩個例外:

    1.sizeof(數(shù)組名) - 這里的數(shù)組名不是首元素的地址,是表示整個數(shù)組的,這里計算的是整個數(shù)組的大小,單位還是字節(jié)。

    2.&數(shù)組名 - 這里的數(shù)組名不是首元素的地址,是表示整個數(shù)組的,拿到的是整個數(shù)組的地址

    int main()
    {
    	int arr[10] = { 0 };
    	int sz = sizeof(arr);
    	printf("%d\n", sz);
    	return 0;
    }
    int main()
    {
    	int arr[10] = { 0 };
    	int* p = arr;
    	int i = 0;
    	int sz = sizeof(arr) / sizeof(arr[0]);
    	for (i = 0;i < sz;i++)
    	{
    		*(p + i) = i;
    	}
    	for (i = 0;i < sz;i++)
    	{
    		printf("%d ", *(p + i));
    	}
    	return 0;
    }

    6.二級指針

    我們都知道,指針變量是變量,是變量就有地址,那么指針變量的地址存放在哪里呢?

    這就是我們要了解的二級指針。

    int main()
    {
        int a = 10;
        int* p = &a;
        int** pp = &p;//pp就是二級指針
        **pp = 20;
        printf("%d\n", a);//a = 20
        return 0;
    }

    7.指針數(shù)組

    從名字上來看,大家覺得指針數(shù)組是指針還是數(shù)組?

    答案是數(shù)組,是存放指針的數(shù)組。

    整型數(shù)組 - 存放整型的數(shù)組就是整型數(shù)組

    字符數(shù)組 - 存放字符的數(shù)組就是字符數(shù)組

    指針數(shù)組 - 存放指針的數(shù)組就是指針數(shù)組

    int* 整型指針的數(shù)組

    char* 字符指針的數(shù)組

    int main()
    {
    	int arr[10];
    	char ch[5];
    	int* parr[5];
    	char* pc[6];
    	return 0;
    }
    int main()
    {
    	int a = 10;
    	int b = 20;
    	int c = 30;
    	int* parr[3] = { &a,&b,&c };
    	for (int i = 0;i < 3;i++)
    	{
    		printf("%d\n", *(parr[i]));
    	}
    	return 0;
    }

    上述內(nèi)容就是怎樣理解C語言中的初階指針,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI