CLASS 5 指標.

Slides:



Advertisements
Similar presentations
第一單元 建立java 程式.
Advertisements

Introduction to C Programming
計算機程式語言實習課.
陣列 Array chapter 3 德明科技大學資訊科技系.
陣列與字串 Java陣列特性 一維陣列 多維陣列 字串 字串的相關函數 字串緩衝器類別.
C/C++基礎程式設計班 陣列 (Array)
TQC+ JAVA全國教師研習會 PLWeb 程式設計練習平台 簡介.
C語言中可變参數的用法——va_list、va_start、va_arg、va_end参數定義
第十一章 結構.
第 7 章 陣列與指標.
Visual C++ introduction
簡易C++除錯技巧 長庚大學機械系
Chen Yi Fen The C Language Chen Yi Fen
列舉(enum).
【變數與記憶體位址】 變數(Variable)提供一個有名稱的記憶體儲存空間。一個變數包含資料型態、變數本身的值及它的位址值。
101北一女中 資訊選手培訓營 快速排序函式qsort() Nan.
String C語言-字串.
保留字與識別字.
101北一女中 資訊選手培訓營 妳不可不了解的指標 Nan.
C語言簡介 日期 : 2018/12/2.
類別(class) 類別class與物件object.
SQL Stored Procedure SQL 預存程序.
Chapter 7 指標.
指標 林錦財.
Methods 靜宜大學資工系 蔡奇偉副教授 ©2011.
第3章 指標與字串 (Pointers and Strings)
Java 程式設計 講師:FrankLin.
Introduction to the C Programming Language
JAVA 程式設計與資料結構 第四章 陣列、字串與數學物件.
Chap3 Linked List 鏈結串列.
Introduction to the C Programming Language
|12 結構與列舉型態.
程式設計實習課(四) ----C 函數運用----
C programming.
第一單元 建立java 程式.
複習 int a[5]; int i; //a[0], a[1], a[2], a[3], a[4]
陣列(Array).
選擇性結構 if-else… switch-case 重複性結構 while… do-while… for…
陣列
C++ 程式初探 III.
輸入&輸出 函數 P20~P21.
第十章 指標.
第7章 指標 7-1 指標的基礎 7-2 指標變數的使用 7-3 指標運算 7-4 指標與陣列 7-5 指向函數的指標.
認識常數與變數 學習C++所提供的各種基本資料型態 瞭解溢位的發生 學習認識資料型態之間的轉換
向量 (vector) 就是典型的一維陣列,而更高維的矩陣,例如矩陣 (matrix) 和張量 (tensor) 則分別是二維和三維的陣列。
函數 博碩文化出版發行.
引用檔案.
C qsort.
程式設計-- Binary Search 通訊一甲 B 楊穎穆.
第14章 結構與其他資料形式.
陣列與結構.
指標 (pointer) 是一種特別的資料型態,用來儲存某一資料在記憶體內的位址。
北一女中 資訊選手培訓營 妳不可不了解的指標 Nan.
選擇性結構 if-else… switch-case 重複性結構 while… do-while… for…
實習八 函式指標.
程式設計--Quick Sort 通訊一甲 B 楊穎穆.
第四章 陣列、指標與參考 4-1 物件陣列 4-2 使用物件指標 4-3 this指標 4-4 new 與 delete
作業系統實習課(二) -Scheduler-Related System Calls-
Programming & Language Telling the computer what to do
Introduction to the C Programming Language
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
Array(陣列) Anny
Class 3:陣列.
C語言程式設計 老師:謝孟諺 助教:楊斯竣.
Introduction to the C Programming Language
台大資訊工程學系 資訊系統訓練班 第119期 吳晉賢
Unix指令4-文字編輯與程式撰寫.
方法(Method) 函數.
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
InputStreamReader Console Scanner
Presentation transcript:

CLASS 5 指標

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;

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

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

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

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

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

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

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

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

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也不可變動

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

指標的運算 指標的加減運算,只有對陣列執行時才有意義 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

陣列與指標的交換性 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是指標變數

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

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

存取陣列裡的元素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

練習 將長度為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

指標與多維陣列 多維陣列的記憶體配置 每一個元素在記憶體裡順序,是以最低的維度 排起,由小到大 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]

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

以多維陣列為函式的參數 假設要傳給函式的是一個二維陣列,其宣告是 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]) { } 宣告了一個陣列放了兩個指標變數

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

補充 (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"); }

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

作業六 參見hw6.doc (到www.csie.ntu.edu.tw/~r93041/C下載)

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