|
|
- 之前再網路上搜集到的一份資料 是關於 陣列 還有字串的部份
- 大家常有的 字串 轉int ...等 或許可以參考上面的方法 解決
- [陣列及字串]
- 簡介
- 為什要用陣列? 想像一下如果我們要寫一個程式, 程式要求要輸入全班同學的期中考數學科成績, 寫成程式會長什麼樣子?
- #include < stdio.h >
- void main(void)
- {
- int num1, num2, num3, num4, num5;
- scanf("%d",&num1);
- scanf("%d",&num2);
- scanf("%d",&num3);
- scanf("%d",&num4);
- scanf("%d",&num5);
- }
- 上面的程式是全班只有5位學生時的情形, 那要是全班有50位學生時, 程式要怎麼寫? 這時就可求助於陣列(Array)
- #include < stdio.h >
- void main(void)
- {
- int i;
- int student[50];
-
- for ( i=0; i<50; i++ )
- {
- scanf("%d", &student);
- }
- }
- 程式碼明顯的精簡許多, 用原先的寫法最少要宣告50個變數, 還要寫50個scanf.
- 使用#define的好處在這�奡N可以看出來.
- #include < stdio.h >
- #define STUDENTS 5
- void main(void)
- {
- int i;
- int student[STUDENTS];
- // 只要改define中STUDENTS的數值, 陣列大小和迴圈要跑的次數都會同時改變
- for ( i=0; i < STUDENTS; i++ )
- {
- scanf("%d", &student);
- printf("I get %d\n",student);
- }
- }
- 簡單的來說, 陣列就是一次宣告出許多個相同型態的變數來使用.
- int a[5];
- 上面的語法會宣告出5個整數, 要取用陣列中的某個變數來用時, 要給一個索引值, 要取用這5個整數的方法分別是
- a[0]=1; // 把a[0]設定為1
- a[1]=2; // 把a[1]設定為2
- a[2]=3; // 把a[2]設定為3
- a[3]=4; // 把a[3]設定為4
- a[4]=5; // 把a[4]設定為5
- a[5]是不存在的.
- 宣告大小為N時, 取用的索引值範圍為0,1,2,.....N-1
- 第二節:一維陣列的使用
- 宣告陣列時, 同樣一開始可以設定好它們的初值
- void main(void)
- {
- int a[5]={1,2,3,4,5};
- // 設定 a[0]=1, a[1]=2, a[2]=3, a[3]=4, a[4]=5
- int b[]={1,2,3};
- // 若size沒指定, 因為給了3個數字, 在此會自動設定為b[3];
- }
- 設定陣列時, 還常和迴圈一起使用
- void main(void)
- {
- int a[5];
- int i;
- for ( i=0; i<5; i++ )
- {
- a=i;
- }
- // 設定a[0]=0, a[1]=1, a[2]=2, a[3]=3, a[4]=4
- }
- 讀入5個數字, 求出它們的平均值.
- #include < stdio.h >
- #define NUM 5
- void main(void)
- {
- int i;
- float sum=0;
- float aver;
- float num[NUM];
-
- // 分別讀入5個數值
- for ( i=0; i < NUM; i++ )
- {
- scanf("%f", &num);
- }
-
- // 計算總和
- for ( i=0; i < NUM; i++ )
- {
- sum+=num;
- }
- // 求平均值
- aver=sum/(float)NUM;
- printf("average=%f\n",aver);
- }
- 多維陣列
- 使用陣列時,只用了一個索引值, 叫做一維陣列. 我們可以宣告出需要多個索引值的陣列來.
- void main(void)
- {
- int a[2][2];
- // 這時候, 有a[0][0], a[0][1], a[1][0], a[1][1]等4個變數可以使用
- }
- 設定二維陣列初值的方法為
- void main(void)
- {
- int a[2][2]={ {00, 01},
- {10, 11} };
- int b[2][2]={ 00,01,10,11 };
- }
- 實實上, 陣列在記憶體中都是一塊連續的記憶體空間. 一維陣列時很容易想像:
- int a[5];
- a[0]的位址是&a+0;
- a[1]的位址是&a+1;
- a[2]的位址是&a+2;
- a[3]的位址是&a+3;
- a[4]的位址是&a+4;
- 二維陣列同樣會是一塊連續的記憶體空間
- int a[5][5];
- a[0][0]的位址是&a+0*5+0;
- a[0][1]的位址是&a+0*5+1;
- a[0][2]的位址是&a+0*5+2;
- .....
- a[1][1]的位址是&a+1*5+1;
- .....
- a[x][y]的位址是&a+x*5+y;
- 結論
- int b[N][M];
- b[x][y]的位址是&b+x*M+y;
- int c[N][M][P];
- c[x][y][z]的位址是&c+x*M*P+y*P+z;
- 範例:印出陣列中所有變數的記憶體位址
- #include < stdio.h >
- #define N 3
- #define M 2
- void main(void)
- {
- char a[N][M];
- for ( int i=0; i < N; i++ )
- {
- for ( int j=0; j < M; j++ )
- {
- printf("%d\n",&a[j]);
- }
- }
- }
- 陣列的應用(1)
- 範例:用一維陣列來儲存向量, 把兩個向量相加, 結果記錄在另一個陣列中
- #include < stdio.h >
- #include < stdlib.h >
- #include < time.h >
- #define DIMENSION 3
- #define MAX_NUMBER 10
- void main(void)
- {
- int vector1[DIMENSION];
- int vector2[DIMENSION];
- int vector3[DIMENSION];
- int i;
- // 給定計算亂數的初值
- srand( time(NULL) );
- for ( i=0; i < DIMENSION; i++ )
- {
- // 利用亂數來設定數值
- vector1=rand()%(MAX_NUMBER+1);
- vector2=rand()%(MAX_NUMBER+1);
- }
-
- // 印出vector1的內容
- printf("(");
- for ( i=0; i < DIMENSION; i++ )
- {
- printf("%d ",vector1);
- }
- printf(")+");
- // 印出vector2的內容
- printf("(");
- for ( i=0; i < DIMENSION; i++ )
- {
- printf("%d ",vector2);
- }
- printf(")=");
- // 計算並印出vector3的內容
- printf("(");
- for ( i=0; i < DIMENSION; i++ )
- {
- vector3=vector1+vector2;
- printf("%d ",vector3);
- }
- printf(")\n");
- }
- 範例:記錄全班同學的考試成績, 把低於60分不及格的同學號碼印出來
- #include < stdio.h >
- #include < stdlib.h >
- #include < time.h >
- #define STUDENTS 30
- #define MAX_NUMBER 100
- void main(void)
- {
- int i;
- int student[STUDENTS];
- // 給定計算亂數的初值
- srand( time(NULL) );
- for ( i=0; i < STUDENTS; i++ )
- {
- // 利用亂數來設定數值
- student=rand()%(MAX_NUMBER+1);
- }
-
- for ( i=0; i < STUDENTS; i++ )
- {
- if ( student < 60 )
- {
- printf("Student %d get %d points, fail!\n", i, student);
- }
- }
- }
- 字串
- 在程式語言中, 一個英文單字, 一個句子, 都可以當成一個字串. 簡單的說, 要記錄size超過一個字母的東西, 就叫做一個字串. 在C語言中, 一個一維的的字元陣列可以當成一個字串.
- #include < stdio.h >
- void main(void)
- {
- char a[]={"Hello"};
- printf("%s \n",a);
- }
- 上面的寫法, 相當於
- #include < stdio.h >
- void main(void)
- {
- char a[6];
- a[0]='H';
- a[1]='e';
- a[2]='l';
- a[3]='l';
- a[4]='o';
- a[5]='\0'; // a[5]=0; 0是字串的結束符號
- printf("%s \n",a);
- }
- 或是
- #include < stdio.h >
- void main(void)
- {
- char a[6]={'H','e','l','l','o','\0'};
- printf("%s \n",a);
- }
- 利用scanf來讀取一個字串的方法如下
- #include < stdio.h >
- void main(void)
- {
- char a[80];
- scanf("%s",a);
- printf("%s \n",a);
- }
- 用scanf來讀字串, 字串中不能有空白. 若有空白會被當成兩個不同的字串. 要讀取有空白的字串要用gets;
- #include < stdio.h >
- void main(void)
- {
- char a[80];
- gets(a);
- printf("%s \n",a);
- }
- 字串不能直接互相做比對, 下面的程式是沒有意義的
- #include < stdio.h >
- void main(void)
- {
- char a[]="Hello";
- char b[]="How are you";
- // 下面的比較會變成 &a 和 &b 這兩個位址互相去比較
- if ( a==b )
- {
- printf("a==b\n");
- }
- }
- 比較字串要用C的庫存函式strcmp
- #include < stdio.h >
- #include < string.h >
- void main(void)
- {
- char a[]="Hello";
- char b[]="How are you";
- if ( strcmp(a,b)==0 )
- {
- printf("a==b\n");
- }
- else
- {
- printf("a!=b\n");
- }
- }
- 定義在string.h中經常使用的函式有 函式名稱 用途
- strcpy copy字串
- strcat 把一個字串插到另一個字串的後面
- strlen 計算字串的長度
- 範例:
- #include < stdio.h >
- #include < string.h >
- void main(void)
- {
- char a[80]="Hello,";
- char b[]=" how are you?";
- char c[80];
- strcat(a,b);
- printf("%s\n",a);
- strcpy(c,a);
- printf("%s\n",c);
- printf("%d\n", strlen(c) );
- }
- 字串應用(1)
- 範例:把一個字串反過來
- #include < stdio.h >
- #include < string.h >
- #define MAX_STRING 80
- void main(void)
- {
- char a[MAX_STRING];
- char b[MAX_STRING];
- int len;
- int i,j;
-
- gets(a);
- len=strlen(a);
- for ( i=0, j=len-1; i < len; i++, j-- )
- {
- b[j]=a;
- }
- b[len]='\0';
- printf("%s \n",b);
- }
- 範例:把字串中的空白字元都拿掉
- #include < stdio.h >
- #include < string.h >
- #define MAX_STRING 80
- void main(void)
- {
- char a[MAX_STRING];
- char b[MAX_STRING];
- int len;
- int i,j;
-
- gets(a);
- len=strlen(a);
- for ( i=0, j=0; i <= len; i++ )
- {
- if ( a!=' ' )
- b[j++]=a;
- }
- printf("%s \n",b);
- }
- 另一種解法
- #include < stdio.h >
- #include < string.h >
- #define MAX_STRING 80
- void main(void)
- {
- char a[MAX_STRING];
- int len;
- int i,j;
-
- gets(a);
- len=strlen(a);
- for ( i=0, j=0; i < len; i++ )
- {
- if ( a!=' ' )
- a[j++]=a;
- }
- a[j]='\0';
- printf("%s \n",a);
- }
- 第五節:字串進階
- 如果字串當中的字元都是數字, C的庫存函式中有提供把字串轉換回數字的函式.
- #include < stdio.h >
- #include < stdlib.h >
- void main(void)
- {
- char string[]="100";
- char string2[]="0.5";
- int num;
- double num2;
- num=atoi(string);
- // 函式atoi可以把字串換算成整數
- num2=atof(string2);
- // 函式atof可以把字串換算成浮點數
- printf("%d %lf\n",num,num2);
- }
- 用sscanf也可以做到同樣的效果
- #include < stdio.h >
- #include < stdlib.h >
- void main(void)
- {
- char string[]="100";
- char string2[]="0.5";
- int num;
- double num2;
- sscanf(string,"%d",&num);
- sscanf(string2,"%lf",&num2);
- // sscanf和scanf用法一樣, 只是輸入的來源改成從字串中讀取而不是從鍵盤
- printf("%d %lf\n",num,num2);
- }
- 相對地, 數字也可以反回去轉成字串, 這要用sprintf來做到.
- #include < stdio.h >
- #include < stdlib.h >
- void main(void)
- {
- char string[80];
- int num=5;
- float fnum=0.5;
- sprintf(string,"num=%d fnum=%f",num,fnum);
- // sprintf的用法和printf完全相同,
- // 只是printf把結果印在螢幕上, sprintf把結果印到一個字串中.
- printf("%s\n",string);
- }
- atoi及atof函式本身的運作原理很簡單, 其實就是一個一個字元去把數字算出來而已. 下面是一個簡單的atoi函式的過程.
- // 模擬atoi函式的運作
- #include < stdio.h >
- #include < stdlib.h >
- #include < string.h >
- void main(void)
- {
- char string[80];
- int i;
- int len;
- int num;
- gets(string);
- len=strlen(string);
- num=0;
- for ( i=0; i < len; i++ )
- {
- num*=10;
- num+=string-'0';
- }
- printf("%d\n",num);
- }
- sprintf的原理也是一個一個數字把它再換回去成為字元而已, 下面是一個把數字轉回字串的程式
- #include < stdio.h >
- #include < stdlib.h >
- #include < string.h >
- void main(void)
- {
- char string[80];
- char temp;
- int i,j;
- int len;
- int num;
- scanf("%d",&num);
- len=0;
- do
- {
- string[len++]='0'+num%10;
- num/=10;
- }while(num>0);
- string[len]='\0';
- // 字串反轉
- for ( i=0, j=len-1; i < len/2; i++,j-- )
- {
- temp=string[j];
- string[j]=string;
- string=temp;
- }
- printf("%s\n",string);
- }
- 為什麼會需要用到sprintf?有很多情形下, 不會使用到printf來做輸出. 像是在視窗作業系統開啟一個Message Box來顯示訊息. 此時就需要先把需要輸出的數字都轉成字串, 再透過WIN32 API 函式來秀出訊息.
- 範例:開啟一個MessageBox來顯示計算求得的正方形面積
- #include < stdio.h >
- #include < windows.h >
- void main(void)
- {
- char string[80];
- int r;
- int area;
- scanf("%d",&r);
- area=r*r;
- sprintf(string,"Area=%d",area);
- MessageBox(NULL,string,"Hello",MB_OK);
- // Win32 API之一, 會開啟一個簡單的message box, 印出第2個參數的字串內容
- }
- 那為什麼需要用到atoi/atof?用scanf來讀鍵盤時,使用者可能會輸入錯誤. 例如說要輸入數字卻輸入字元. 比較好的方法就是scanf中讀進去的東西都先把它當成字串, 檢查字串中有沒有不合理的東西出現. 不合理就要求重新輸入, 合理的話才把字串轉成數字.
- #include < stdio.h >
- #include < stdlib.h >
- #include < string.h >
- void main(void)
- {
- char string[80];
- int num;
- int len;
- while(1)
- {
- printf("Please input an integer:");
- scanf("%s",string);
- // 檢查字串中有沒有不是數字的字元出現
- len=strlen(string);
- for ( int i=0; i < len; i++ )
- {
- if ( string < '0' || string > '9' )
- break;
- }
- // 如果每個字元都是'0','1',...'9'當中的任一個, 就跳出迴圈
- if ( i==len )
- break;
- }
- num=atoi(string);
- printf("I get %d\n",num);
- }
複製代碼 |
|