Presentation is loading. Please wait.

Presentation is loading. Please wait.

CLASS 5 指標.

Similar presentations


Presentation on theme: "CLASS 5 指標."— Presentation transcript:

1 CLASS 5 指標

2 int my_abs(int); int rect(int,int); int main(){ int x,y,r; printf(“請輸入長方型的長:”); scanf(“%d”,&x); printf(“請輸入長方型的寬:”); scanf(“%d”,&y); printf(“長方型的面積:%d\n”,rect(my_abs(x), my_abs(y))); return 0; } int rect(int x,int y){ return x*y; int my_abs(int num){ if(num<0)num*=-1; return num;

3 複習 srand(time(NULL)); int rand_num=(rand()%901)+100;//100~1000
printf(“亂數:%d, 平方根%lf\n”,rand_num,sqrt(rand_num));

4 想一想 下面這個函式作什麼事情? 應該是交換num1和num2,但其實並沒有,why?
因為上面的函式只是把變數的值傳進去,函式更改 的是變數的複製品,而不是真正變數在記憶體存放 的值

5 何謂指標? 一般正常的變數 儲存的是程式當中用來記錄或是做計算用的數值 指標變數 變數的內容儲存的是另一個變數的記憶體位址值

6 兩個運算子 取址運算子(&) 取得一個變數的記憶體位址 提領運算子(*) 間接讀取指標所指向的記憶體位址資料

7 指標變數的宣告 語法 資料型態代表這個指標變數所存放的位址要以 什麼樣的資料型態(記憶體大小)來解讀 int *countPtr;
資料型態 *指標變數名稱; 資料型態代表這個指標變數所存放的位址要以 什麼樣的資料型態(記憶體大小)來解讀 int *countPtr; 指定初始值的宣告 Int count; int *countPtr=&count;

8 範例練習 實地操作變數、指標變數以及*、&運算子,並 觀察結果 0022FF74 0022FF70 countPtr 8 count

9 為什麼要用指標? 當我們希望傳入的引數在函式中修改其值時, 我們必須利用指標變數來取得修改的權利
如果只有一個需要改變,也可利用return 指標變數代表一個位址,假如我們有一塊很大 的連續記憶體(如陣列)要傳入函式,使用指 標變數是有效率的 因為在參數初始化時,只需複製一個位址,而不必 將整個連續記憶體的內容都複製一份 交換兩個複雜資料型態的變數時,只需交換指 向它們位址的指標即可,增加程式運算的速度

10 範例練習 撰寫一個真正可以交換兩數的函式,並在主函 式呼叫它

11 const常數修飾子 int *ptr; int *const ptr; const int *ptr;
ptr可變動,*ptr也可變動 int *const ptr; ptr不可變動,*ptr可變動 const int *ptr; ptr可變動,*ptr不可變動 const int *const ptr; ptr不可變動,*ptr也不可變動

12 指標與陣列名稱 宣告陣列時,陣列的名稱本身就可以看作是一 個指標 常數指標 不能更改這個常數指標的值
存放的位址 陣列第一個元素在記憶體的位址 利用索引和這個記憶體位址,我們可以取得陣列中 各元素的值 int array[5]; array是一個位址//printf(“%d”,array); //array[0]放在array+0*sizeof(int)的位址 //array[2]放在array+2*sizeof(int)的位址

13 指標的運算 指標的加減運算,只有對陣列執行時才有意義 int arr[6], *ptr=arr;
因為我們不能假設相同型態的兩個變數一定會連續地存 放在記憶體中,除非它們是同一陣列內相鄰的兩個元素 int arr[6], *ptr=arr; printf(“%d”,*ptr); //印出100 ptr++; printf(“%d”,*ptr); //印出200 ptr+=2; printf(“%d”,*ptr); //印出400 printf(“%d”,ptr-arr); //印出3 100 200 300 400 500 600

14 陣列與指標的交換性 int arr[10],*ptr; ptr=arr; /*這兩行 ptr=&arr[0]; 做的是一樣的事情*/
int arr[10],*ptr=arr; //ptr為一指向arr的指標 arr[2]、*(arr+2)、ptr[2]、*(ptr+2)是相同的東西 注意 陣列與指標不同在於陣列名稱是常數指標 arr++; 不合法,因為arr是常數指標,不可更改指向位址 ptr++; 合法,ptr是指標變數

15 存取陣列裡的元素 使用[ ]陣列運算子 使用*提領運算子
array[i],i值決定要取用從array位址起算要位移幾 個元素長度,單位元素長度(記憶體大小)取決於 陣列的資料型態 使用*提領運算子 array+i,表示從array這個位址,位移i個單位元素 的位址,單位同樣取決於陣列的資料型態 給定位址後,配合提領運算子,取用第i個元素即 是用*(array+i)

16 指標與一維陣列 宣告一維陣列,程式執行時,系統會保留一塊 連續的記憶體 int array[8]; 陣列array
25 35 18 29 100 121 5 9

17 存取陣列裡的元素2 (array+1)[2]表示的是*(array+1+2)也就是array[3]的 位置 注意
因為*運算子的優先權大於+,所以*array+i表示的是這 個位址的元素値加上i *(array+2)是18 *array+2是 25+2=27 *(array+2)是可接受數值的變數(可以放在指定運算子 =的左邊),但*array+2只是一個數值而已 array+1 array+1[2] 25 35 18 29 100 121 5 9

18 練習 將長度為5的一維陣列傳入函式 在函式內將陣列裡面的值-5 在主程式印出新的值 void sub_five(int*);
(用rand()產生5~105的值) 在函式內將陣列裡面的值-5 在主程式印出新的值 void sub_five(int*); int main(){ int i,num[5]; srand(time(NULL)); //亂數產生5個值,並印出 sub_five(num); //印出陣列裡新的值 } void sub_five(int* num){ //將陣列裡的值減5

19 指標與多維陣列 多維陣列的記憶體配置 每一個元素在記憶體裡順序,是以最低的維度 排起,由小到大 int num[3][2];
num[0] num[1] num[2] num所指的單位元素是一個擁有2個整數的一維 陣列 num[0][0] num[0][1] num[1][0] num[1][1] num[2][0] num[2][1]

20 指標與多維陣列2 在陣列宣告時,指定了較低的維度擁有2個元素, 編譯器 (compiler)看見num[1]才知道往後移動的 一個單位是一個長度為2個整數的一維陣列 存取num[1][0]的寫法 num[1][0] (*(num+1))[0] *(*(num+1)+0) *(num[1]+0) 使用提領運算子後,*(num+1)仍然是一個指標

21 以多維陣列為函式的參數 假設要傳給函式的是一個二維陣列,其宣告是 int num[3][2];
函式的參數列:void test(int num2[3][2]) { } 參數num2所指的是一個擁有兩個整數的一維陣列,總共有三 個這樣的一維陣列 相同寫法 void test(int num2[ ][2]) { } void test(int (* num2)[2]) { } 不合法的寫法 void test(int *num2[2]) { } 宣告了一個陣列放了兩個指標變數

22 指標的指定與轉換 int num[3][2], *num2; num2=num;
不合法的指定敘述 因為num2所指的元素是一個整數,而num所指的元素是一個 一維陣列 仍然可以透過強制型態轉換,把num2成功的指向num所 指的位址。 num2=(int *)num; num2跟num分享同樣的位址 num num2[1] num2[2] num2[3] num2[4] num2[5] num[0][0] num[0][1] num[1][0] num[1][1] num[2][0] num[2][1]

23 補充 (malloc and free) int main(){ int *pt; int size,i;
printf("請輸入陣列的大小: "); scanf("%d",&size); pt=(int*)malloc(sizeof(int)*size); for(i=0;i<size;i++) pt[i]=rand()%10+1; printf("%d ",pt[i]); free(pt); system("pause"); }

24 補充 (malloc and free) (指標的型態)malloc (sizeof(陣列的資料型態)*陣列大小); 範例
float* pt=(float*)malloc(sizeof(float)*size); char* pt=(char*)malloc(sizeof(char)*size);

25 作業六 參見hw6.doc (到

26 作業六(也可以試著做這一個) 讓使用者輸入陣列的大小,並產生int陣列 讓使用者輸入值到陣列裡 將陣列傳到一個自訂的函式裡,做排序
提示:用malloc 讓使用者輸入值到陣列裡 將陣列傳到一個自訂的函式裡,做排序 在主函式輸出排序結果


Download ppt "CLASS 5 指標."

Similar presentations


Ads by Google