指標變數課堂實習 I

命令列編譯方式

如果你希望在 cmd 視窗內編譯並執行你的程式的話, 可以把下面這段命令拷貝到一個檔案中, 並且命名為 clcc.bat,
@echo off set ccpath=C:\Program Files\Microsoft Visual Studio 8\VC set oldpath=%path% set path=%path%;%ccpath%\bin @echo on %bcpath%\bin\cl -L%ccpath%\lib -I%ccpath%\include %1 %2 %3 %4 %5 %6 %7 @echo off set path=%oldpath% set ccpath= @echo on


接下來你可以運用下面的命令來編譯/連結你的 prog1.c 程式:

此命令會產生 prog1.exe 的可執行檔案, 再輸入

就可以執行程式了。

詳細請參考 C 程式的開發流程

程式一:這個程式提供基本的功能,不用函式、陣列、及指標

#include <stdio.h> void main(void) { float x, sum=0.0; int i; for (i=0; i<10; i++) { scanf("%f",&x); sum += x; } printf("The sum of 10 numbers is %f\n",sum); }

程式二:這個程式運用陣列來存放讀入的資料

#include <stdio.h> void main(void) { float x[10], sum=0.0; int i; for (i=0; i<10; i++) { scanf("%f",&x[i]); sum += x[i]; } printf("The sum of 10 numbers is %f\n",sum); }

紅字部份是和前一個程式不一樣的地方。
這個程式沒有必要使用陣列來存放資料, 最主要是讓你再熟悉一次陣列的用法, 程式四運用函式來讀取資料時就需要用陣列了。

程式三:讓使用者自己決定他要輸入幾個資料

#include <stdio.h> void main(void) { float x[10], sum=0.0; int i, num; printf("Please input the number of items: "); scanf("%d",&num); for (i=0; i<num; i++) { scanf("%f",&x[i]); sum += x[i]; } printf("The sum of %d numbers is %f\n",num,sum); }

程式四:讓我們把輸入資料寫成一個函式,以免干擾主程式的邏輯

#include <stdio.h> int input(float []); void main(void) { float x[10], sum=0.0; int i, num; if ((num=input(x)) > 0) { for (i=0; i<num; i++) sum += x[i]; printf("The sum of %d numbers is %f\n",num,sum); } else printf("You did not enter any number\n"); } int input(float ary[]) { int numOfItems; int i; printf("Please input the number of items: "); scanf("%d",&numOfItems); for (i=0; i<numOfItems; i++) scanf("%f",&ary[i]); return numOfItems; }

在傳遞陣列到函式內使用時, 函式參數雖然宣告 float ary[], 函式內部也把 ary 當成一個陣列來使用, 但是實際上並沒有一個新的陣列 ary, 在函式內所使用到的陣列 ary 陣列根本就是 main() 函式內的 float x[10] 陣列, ary 陣列可以看成是 x 陣列的一個別名。

嚴格來說, 在函式 input() 內 ary 只是一個浮點指標常數, 其資料為 x (變數 x[0] 之位址), (既然只是浮點指標常數而已, 所以記憶體內沒有保留存放浮點數的陣列資料, 只保留了存放一個記憶體位址的區域), 在函式參數的地方宣告 float ary[] 和宣告 float * const ary 是完全等效的, 下一個程式就是讓你嘗試看看。

程式五:指標常數 vs. 陣列參數

#include <stdio.h> int input(float []); void main(void) { float x[10], sum=0.0; int i, num; if ((num=input(x)) > 0) { for (i=0; i<num; i++) sum += x[i]; printf("The sum of %d numbers is %f\n",num,sum); return; } else printf("You did not enter any number\n"); } int input(float * const ary) { int numOfItems; int i; printf("Please input the number of items: "); scanf("%d",&numOfItems); for (i=0; i<numOfItems; i++) scanf("%f",&ary[i]); return numOfItems; }

請注意:

程式六:既然是指標當然可以用指標的運算和存取方法

#include <stdio.h> int input(float []); void main(void) { float x[10], sum=0.0; int i, num; if ((num=input(x)) > 0) { for (i=0; i<num; i++) sum += x[i]; printf("The sum of %d numbers is %f\n",num,sum); return; } else printf("You did not enter any number\n"); } int input(float *ary) { int numOfItems; int i; printf("Please input the number of items: "); scanf("%d",&numOfItems); for (i=0; i<numOfItems; i++) scanf("%f",ary+i); return numOfItems; }

程式七:函式利用參數 ptrNum 回傳一個資料 num

#include <stdio.h> void input(int *, float []); void main(void) { float x[10], sum=0.0; int i, num; input(&num, x); if (num > 0) { for (i=0; i<num; i++) sum += x[i]; printf("The sum of %d numbers is %f\n",num,sum); } else printf("You did not enter any number\n"); return; } void input(int *ptrNum, float *ary) { int i; printf("Please input the number of items: "); scanf("%d",ptrNum); for (i=0; i<*ptrNum; i++) scanf("%f",&ary[i]); return; }

請注意什麼時候該用 * 號,什麼時候該用 & 號。

程式八:再一次說明既然是指標當然可以用指標的運算和存取方法

#include <stdio.h> void input(int *, float []); void main(void) { float x[10], sum=0.0; int i, num; input(&num, x); if (num > 0) { for (i=0; i<num; i++) sum += x[i]; printf("The sum of %d numbers is %f\n",num,sum); } else printf("You did not enter any number\n"); } void input(int *ptrNum, float ary[]) { int i; printf("Please input the number of items: "); scanf("%d",ptrNum); for (i=0; i<*ptrNum; i++) scanf("%f",ary+i); return; }

程式九:觀念驗證

這個程式如果你懂了的話, 你應該已經知道 C 編譯器是如何對待參數的型態, 你已經完全暸解到:

記憶體 (變數) 是用來存放資料的, 不管你將它宣告成什麼型態, 只要保留的記憶體夠多, CPU 可以把適當的資料存放進去, 等到需要使用的時候就可以再把其內存放的資料拿出來使用。

在程式中宣告變數的型態的目的, 是編譯器用來區分模凌兩可的語法用的, 是用來幫你做自動型態轉換用的, 卻無法限制 CPU 在其內要存放什麼樣子的資料。

當然你不要學這個程式, 程式是要寫來讓人家看的, 編譯器的型態檢查是幫助你寫程式的, 別玩弄它。


#include <stdio.h> void input(int, float []); void main(void) { float x[10], sum=0.0; int i, num; input((int)&num, x); // 將 num 的位址 &num 存放在參數變數 ptrNum 中 if (num > 0) { for (i=0; i<num; i++) sum += x[i]; printf("The sum of %d numbers is %f\n",num,sum); } else printf("You did not enter any number\n"); } void input(int ptrNum, float ary[]) // 宣告一個 2 bytes 的參數變數 ptrNum { int i; printf("Please input the number of items: "); scanf("%d",ptrNum); for (i=0; i<*(int *)ptrNum; i++) // 將參數變數 ptrNum 內存放的資料讀出來當作一個整數位址 (int *) 來用 scanf("%f",ary+i); return; }

以上我們假設位址是 16 bits, int 型態變數也是 16 bits。

程式設計課程 首頁

製作日期: 09/13/2008 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@mail.ntou.edu.tw TEL: 02 24622192x6615
海洋大學 電機資訊學院 資訊工程學系 Lagoon