1. 程式人生 > >讓你不再害怕指標的應用-全程模擬+註解(第二部分陣列)

讓你不再害怕指標的應用-全程模擬+註解(第二部分陣列)

讓你不再害怕指標的應用-全程模擬+註解(第二部分:陣列)(持續更新)

寫此文章一是為了分享,二是為了溫習!

預計包含的內容為:變數如int  、陣列  、結構體  、列舉 、聯合體、(這個自己也在瞭解)。

軟體:CODE::Blocks      Compiler:GCC5.1.0

寫第二部分就預設大家看了我寫的之前的文章,那我就直接闡述我的觀點和模擬結果!

重要的五句話:好好揣摩!

指標的值: 是它所指向物件的地址
           在指標前面使用*可以得到:指標所指向物件的值(簡稱:取內容)
           指標+1,指標的值遞增它所“指向型別”的大小
           陣列的指標:指的是:陣列的起始地址。
           陣列元素的指標:指:陣列元素的地。

 

把陣列的地址 賦給指標變數 :該指標就指向該陣列了!

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include<windows.h>
int b = 0;
int c ;
int main()
{
    int a[10] = {1,2,3,4,5,6,7,8,9,0};
    int *p_1,*p_2;
    p_1 = &a;//陣列名就是改陣列的首地址
    p_2 = &a[0];//取a的首地址,性質和上面一樣。
    printf("p_1= %d\n",*p_1);
    printf("p_2= %d\n",*p_2);
    printf("a= %d\n",a);
    printf("取內容p_1= %d\n",*p_1);
    printf("去內容p_2= %d\n",*p_2);
    getch();
}

結果:

總結:由上面上來講,取陣列[0]的地址,取a的地址或者直接打印出來的都是一個地址,說明這三種方法都可以得到陣列的地址!

為什麼這麼做呢?C Primer Plus書籍 有這麼一句話我抄下來供閱讀一下!

指標提供一種以符號的形式使用地址的方法。因為計算機的硬體指令非常依賴地址,指標在某種程度上把程式設計師想要表達的指令以更接近機器的方式表達。所以使用指標更有效率!

那麼你就會發現一個問題,如果指標*(p_1+1),*(p_1+1) 取出來的內容是什麼呢?是不是亂碼還是自己想要的資料呢?

想要得到這個問題的答案,我們先看看指標(p_1+1),(p_1+1)打印出來的是什麼呢?我還想表達另一個問題,故改了一下程式!

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include<windows.h>
int b = 0;
int c ;
int main()
{
    int  a[3] = {1,2,3};
    double b[3] = {4,5,6};
    int  *p_1;
    double *p_2;
    p_1 = &a;//陣列名就是改陣列的首地址
    p_2 = &b;
    printf("p_1= %d\n",(p_1));//列印陣列的首地址
    printf("p_2= %d\n",(p_2));
    printf("p_1+1= %d\n",(p_1+1));//列印指標指向的下一個地址
    printf("p_2+1= %d\n",(p_2+1));
    getch();
}

結果:

結論p_1= 6356732 p_1+1= 6356736  p_1= 6356704  p_1+1= 6356712  ,一個int型的變數佔用4個位元組,一個double佔用8個位元組。之前是講過的,不再贅述。說明指標指向下一個地址是可以確定的,為什麼p_1+1指向的地不是6356733呢?也加1呢?

這麼高深的問題,C Primer Plu書籍 來給你解答:我們的系統地址是按位元組編地址的,在C語言中,指標+1指的是增加一個儲存單元,int的儲存單元是4個位元組,那麼pointer+1也就指向下一儲存單元了。

這是為什麼必須宣告的所指向物件型別的原因之一。只知道地址不夠,因為計算機要知道儲存物件需要多少位元組(即使指標所指向的是標量變數,也要知道變數的型別,否則*poiner+1就無法正確取回地址上的值。

明白了這個指標+的問題,我們開始取數組裡面的內容,並且改變數組裡面的值。那不是輕而易舉,哈哈!看程式

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include<windows.h>
int b = 0;
int c ;
int main()
{
    int  a[3] = {1,2,3};//初始化陣列
    double b[3] = {4,5,6};
    int  *p_1;
    double *p_2;
    short i,j;
    p_1 = &a;//陣列名就是改陣列的首地址
    p_2 = &b;
    for(i=0;i<3;i++)
    {
        *(p_1+i) = 100+(i*100);//迴圈修改陣列元素的值
    }
    for(i=0;i<3;i++)
    {
        *(p_2+i) = 400+(i*100);;//迴圈修改陣列元素的值
    }
    for(i=0;i<3;i++)
    {
        printf("p_1+%d= %d\n",i,*(p_1+i));//列印陣列的資料
    }
    for(j=0;j<3;j++)
    {
        printf("p_2+%d= %f\n",j,*(p_2+j));//列印陣列的資料
    }

    getch();
}

結果:

最後我們瞭解陣列的地址,和指向陣列的指標的地址的遞增方式,並也會運用指標取內容,改變變數的值。等等等,我這邊沒有涉及到取地址,因為取地址不是很難理解。

&a  取a的地址,這個地址指標可以指向這個地址;

哈哈,不難吧!

結語:

很多事情學會了就不難了,就比如初中生看小學的知識,高中看初中知識一樣!

寫文章,有很多不足之處,請體諒!我也是邊學別用!