查看: 3159|回復: 0
打印 上一主題 下一主題

[教學] 陣列及字串

[複製鏈接]
跳轉到指定樓層
1#
發表於 2007-8-14 04:43:00 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. 之前再網路上搜集到的一份資料 是關於 陣列 還有字串的部份
  2. 大家常有的 字串 轉int ...等 或許可以參考上面的方法 解決
  3. [陣列及字串]
  4. 簡介
  5. 為什要用陣列? 想像一下如果我們要寫一個程式, 程式要求要輸入全班同學的期中考數學科成績, 寫成程式會長什麼樣子?
  6. #include < stdio.h >
  7. void main(void)
  8. {
  9.         int num1, num2, num3, num4, num5;
  10.         scanf("%d",&num1);
  11.         scanf("%d",&num2);
  12.         scanf("%d",&num3);
  13.         scanf("%d",&num4);
  14.         scanf("%d",&num5);
  15. }

  16. 上面的程式是全班只有5位學生時的情形, 那要是全班有50位學生時, 程式要怎麼寫? 這時就可求助於陣列(Array)
  17. #include < stdio.h >
  18. void main(void)
  19. {
  20.         int i;
  21.         int student[50];
  22.         
  23.         for ( i=0; i<50; i++ )
  24.         {
  25.                 scanf("%d", &student);
  26.         }
  27. }

  28. 程式碼明顯的精簡許多, 用原先的寫法最少要宣告50個變數, 還要寫50個scanf.
  29. 使用#define的好處在這�奡N可以看出來.

  30. #include < stdio.h >

  31. #define STUDENTS 5

  32. void main(void)
  33. {
  34.         int i;
  35.         int student[STUDENTS];
  36.         // 只要改define中STUDENTS的數值, 陣列大小和迴圈要跑的次數都會同時改變
  37.         for ( i=0; i < STUDENTS; i++ )
  38.         {
  39.                 scanf("%d", &student);
  40.                 printf("I get %d\n",student);
  41.         }
  42. }

  43. 簡單的來說, 陣列就是一次宣告出許多個相同型態的變數來使用.
  44. int a[5];
  45. 上面的語法會宣告出5個整數, 要取用陣列中的某個變數來用時, 要給一個索引值, 要取用這5個整數的方法分別是
  46. a[0]=1; // 把a[0]設定為1
  47. a[1]=2; // 把a[1]設定為2
  48. a[2]=3; // 把a[2]設定為3
  49. a[3]=4; // 把a[3]設定為4
  50. a[4]=5; // 把a[4]設定為5
  51. a[5]是不存在的.

  52. 宣告大小為N時, 取用的索引值範圍為0,1,2,.....N-1
  53. 第二節:一維陣列的使用
  54. 宣告陣列時, 同樣一開始可以設定好它們的初值
  55. void main(void)
  56. {
  57.         int a[5]={1,2,3,4,5};
  58.         // 設定 a[0]=1, a[1]=2, a[2]=3, a[3]=4, a[4]=5
  59.         int b[]={1,2,3};
  60.         // 若size沒指定, 因為給了3個數字, 在此會自動設定為b[3];
  61. }

  62. 設定陣列時, 還常和迴圈一起使用
  63. void main(void)
  64. {
  65.         int a[5];
  66.         int i;
  67.         for ( i=0; i<5; i++ )
  68.         {
  69.                 a=i;
  70.         }
  71.         // 設定a[0]=0, a[1]=1, a[2]=2, a[3]=3, a[4]=4
  72. }

  73. 讀入5個數字, 求出它們的平均值.
  74. #include < stdio.h >

  75. #define NUM 5

  76. void main(void)
  77. {
  78.         int i;
  79.         float sum=0;
  80.         float aver;
  81.         float num[NUM];
  82.         
  83.         // 分別讀入5個數值
  84.         for ( i=0; i < NUM; i++ )
  85.         {
  86.                 scanf("%f", &num);
  87.         }
  88.         
  89.         // 計算總和
  90.         for ( i=0; i < NUM; i++ )
  91.         {
  92.                 sum+=num;
  93.         }
  94.         // 求平均值
  95.         aver=sum/(float)NUM;
  96.         printf("average=%f\n",aver);
  97. }

  98. 多維陣列
  99. 使用陣列時,只用了一個索引值, 叫做一維陣列. 我們可以宣告出需要多個索引值的陣列來.
  100. void main(void)
  101. {
  102.         int a[2][2];
  103.         // 這時候, 有a[0][0], a[0][1], a[1][0], a[1][1]等4個變數可以使用
  104. }

  105. 設定二維陣列初值的方法為
  106. void main(void)
  107. {
  108.         int a[2][2]={ {00, 01},
  109.                       {10, 11} };
  110.         int b[2][2]={ 00,01,10,11 };
  111. }

  112. 實實上, 陣列在記憶體中都是一塊連續的記憶體空間. 一維陣列時很容易想像:
  113. int a[5];
  114. a[0]的位址是&a+0;
  115. a[1]的位址是&a+1;
  116. a[2]的位址是&a+2;
  117. a[3]的位址是&a+3;
  118. a[4]的位址是&a+4;

  119. 二維陣列同樣會是一塊連續的記憶體空間
  120. int a[5][5];
  121. a[0][0]的位址是&a+0*5+0;
  122. a[0][1]的位址是&a+0*5+1;
  123. a[0][2]的位址是&a+0*5+2;
  124. .....
  125. a[1][1]的位址是&a+1*5+1;
  126. .....
  127. a[x][y]的位址是&a+x*5+y;
  128. 結論
  129. int b[N][M];
  130. b[x][y]的位址是&b+x*M+y;
  131. int c[N][M][P];
  132. c[x][y][z]的位址是&c+x*M*P+y*P+z;

  133. 範例:印出陣列中所有變數的記憶體位址
  134. #include < stdio.h >

  135. #define N 3
  136. #define M 2

  137. void main(void)
  138. {
  139.         char a[N][M];
  140.         for ( int i=0; i < N; i++ )
  141.         {
  142.                 for ( int j=0; j < M; j++ )
  143.                 {
  144.                         printf("%d\n",&a[j]);
  145.                 }
  146.         }
  147. }

  148. 陣列的應用(1)
  149. 範例:用一維陣列來儲存向量, 把兩個向量相加, 結果記錄在另一個陣列中
  150. #include < stdio.h >
  151. #include < stdlib.h >
  152. #include < time.h >

  153. #define DIMENSION 3
  154. #define MAX_NUMBER 10

  155. void main(void)
  156. {
  157.         int vector1[DIMENSION];
  158.         int vector2[DIMENSION];
  159.         int vector3[DIMENSION];
  160.         int i;

  161.         // 給定計算亂數的初值
  162.         srand( time(NULL) );

  163.         for ( i=0; i < DIMENSION; i++ )
  164.         {
  165.                 // 利用亂數來設定數值
  166.                 vector1=rand()%(MAX_NUMBER+1);
  167.                 vector2=rand()%(MAX_NUMBER+1);
  168.         }
  169.         
  170.         // 印出vector1的內容
  171.         printf("(");
  172.         for ( i=0; i < DIMENSION; i++ )
  173.         {
  174.                 printf("%d ",vector1);
  175.         }
  176.         printf(")+");
  177.         // 印出vector2的內容
  178.         printf("(");
  179.         for ( i=0; i < DIMENSION; i++ )
  180.         {
  181.                 printf("%d ",vector2);
  182.         }
  183.         printf(")=");

  184.         // 計算並印出vector3的內容
  185.         printf("(");
  186.         for ( i=0; i < DIMENSION; i++ )
  187.         {
  188.                 vector3=vector1+vector2;
  189.                 printf("%d ",vector3);
  190.         }
  191.         printf(")\n");
  192. }

  193. 範例:記錄全班同學的考試成績, 把低於60分不及格的同學號碼印出來
  194. #include < stdio.h >
  195. #include < stdlib.h >
  196. #include < time.h >

  197. #define STUDENTS 30
  198. #define MAX_NUMBER 100

  199. void main(void)
  200. {
  201.         int i;
  202.         int student[STUDENTS];
  203.         // 給定計算亂數的初值
  204.         srand( time(NULL) );

  205.         for ( i=0; i < STUDENTS; i++ )
  206.         {
  207.                 // 利用亂數來設定數值
  208.                 student=rand()%(MAX_NUMBER+1);
  209.         }
  210.         
  211.         for ( i=0; i < STUDENTS; i++ )
  212.         {
  213.                 if ( student < 60 )
  214.                 {
  215.                         printf("Student %d get %d points, fail!\n", i, student);
  216.                 }
  217.         }
  218. }

  219. 字串
  220. 在程式語言中, 一個英文單字, 一個句子, 都可以當成一個字串. 簡單的說, 要記錄size超過一個字母的東西, 就叫做一個字串. 在C語言中, 一個一維的的字元陣列可以當成一個字串.
  221. #include < stdio.h >
  222. void main(void)
  223. {
  224.         char a[]={"Hello"};
  225.         printf("%s \n",a);
  226. }

  227. 上面的寫法, 相當於
  228. #include < stdio.h >
  229. void main(void)
  230. {
  231.         char a[6];
  232.         a[0]='H';
  233.         a[1]='e';
  234.         a[2]='l';
  235.         a[3]='l';
  236.         a[4]='o';
  237.         a[5]='\0'; // a[5]=0; 0是字串的結束符號
  238.         printf("%s \n",a);
  239. }

  240. 或是
  241. #include < stdio.h >
  242. void main(void)
  243. {
  244.         char a[6]={'H','e','l','l','o','\0'};
  245.         printf("%s \n",a);
  246. }

  247. 利用scanf來讀取一個字串的方法如下
  248. #include < stdio.h >
  249. void main(void)
  250. {
  251.         char a[80];
  252.         scanf("%s",a);
  253.         printf("%s \n",a);
  254. }

  255. 用scanf來讀字串, 字串中不能有空白. 若有空白會被當成兩個不同的字串. 要讀取有空白的字串要用gets;
  256. #include < stdio.h >
  257. void main(void)
  258. {
  259.         char a[80];
  260.         gets(a);
  261.         printf("%s \n",a);
  262. }

  263. 字串不能直接互相做比對, 下面的程式是沒有意義的
  264. #include < stdio.h >

  265. void main(void)
  266. {
  267.         char a[]="Hello";
  268.         char b[]="How are you";
  269.         // 下面的比較會變成 &a 和 &b 這兩個位址互相去比較
  270.         if ( a==b )
  271.         {
  272.                 printf("a==b\n");        
  273.         }
  274. }

  275. 比較字串要用C的庫存函式strcmp
  276. #include < stdio.h >
  277. #include < string.h >
  278. void main(void)
  279. {
  280.         char a[]="Hello";
  281.         char b[]="How are you";
  282.         if ( strcmp(a,b)==0 )
  283.         {
  284.                 printf("a==b\n");        
  285.         }
  286.         else
  287.         {
  288.                 printf("a!=b\n");
  289.         }        
  290. }

  291. 定義在string.h中經常使用的函式有 函式名稱  用途  
  292. strcpy  copy字串  
  293. strcat  把一個字串插到另一個字串的後面  
  294. strlen  計算字串的長度  

  295. 範例:

  296. #include < stdio.h >
  297. #include < string.h >
  298. void main(void)
  299. {
  300.         char a[80]="Hello,";
  301.         char b[]=" how are you?";
  302.         char c[80];
  303.         strcat(a,b);
  304.         printf("%s\n",a);
  305.         strcpy(c,a);
  306.         printf("%s\n",c);
  307.         printf("%d\n", strlen(c) );
  308. }

  309. 字串應用(1)
  310. 範例:把一個字串反過來
  311. #include < stdio.h >
  312. #include < string.h >

  313. #define MAX_STRING 80

  314. void main(void)
  315. {
  316.         char a[MAX_STRING];
  317.         char b[MAX_STRING];
  318.         int  len;
  319.         int  i,j;
  320.         
  321.         gets(a);
  322.         len=strlen(a);

  323.         for ( i=0, j=len-1; i < len; i++, j-- )
  324.         {
  325.                 b[j]=a;
  326.         }
  327.         b[len]='\0';
  328.         printf("%s \n",b);
  329. }

  330. 範例:把字串中的空白字元都拿掉
  331. #include < stdio.h >
  332. #include < string.h >

  333. #define MAX_STRING 80

  334. void main(void)
  335. {
  336.         char a[MAX_STRING];
  337.         char b[MAX_STRING];
  338.         int  len;
  339.         int  i,j;
  340.         
  341.         gets(a);
  342.         len=strlen(a);

  343.         for ( i=0, j=0; i <= len; i++ )
  344.         {
  345.                 if ( a!=' ' )
  346.                         b[j++]=a;
  347.         }
  348.         printf("%s \n",b);
  349. }

  350. 另一種解法
  351. #include < stdio.h >
  352. #include < string.h >

  353. #define MAX_STRING 80

  354. void main(void)
  355. {
  356.         char a[MAX_STRING];
  357.         int  len;
  358.         int  i,j;
  359.         
  360.         gets(a);
  361.         len=strlen(a);

  362.         for ( i=0, j=0; i < len; i++ )
  363.         {
  364.                 if ( a!=' ' )
  365.                         a[j++]=a;
  366.         }
  367.         a[j]='\0';
  368.         printf("%s \n",a);
  369. }

  370. 第五節:字串進階
  371. 如果字串當中的字元都是數字, C的庫存函式中有提供把字串轉換回數字的函式.
  372. #include < stdio.h >
  373. #include < stdlib.h >
  374. void main(void)
  375. {
  376.         char string[]="100";
  377.         char string2[]="0.5";
  378.         int  num;
  379.         double num2;
  380.         num=atoi(string);
  381.         // 函式atoi可以把字串換算成整數
  382.         num2=atof(string2);
  383.         // 函式atof可以把字串換算成浮點數
  384.         printf("%d %lf\n",num,num2);
  385. }

  386. 用sscanf也可以做到同樣的效果
  387. #include < stdio.h >
  388. #include < stdlib.h >
  389. void main(void)
  390. {
  391.         char string[]="100";
  392.         char string2[]="0.5";
  393.         int  num;
  394.         double num2;
  395.         sscanf(string,"%d",&num);
  396.         sscanf(string2,"%lf",&num2);
  397.         // sscanf和scanf用法一樣, 只是輸入的來源改成從字串中讀取而不是從鍵盤
  398.         printf("%d %lf\n",num,num2);
  399. }

  400. 相對地, 數字也可以反回去轉成字串, 這要用sprintf來做到.
  401. #include < stdio.h >
  402. #include < stdlib.h >
  403. void main(void)
  404. {
  405.         char string[80];
  406.         int  num=5;
  407.         float fnum=0.5;
  408.         sprintf(string,"num=%d fnum=%f",num,fnum);
  409.         // sprintf的用法和printf完全相同,
  410.         // 只是printf把結果印在螢幕上, sprintf把結果印到一個字串中.
  411.         printf("%s\n",string);
  412. }

  413. atoi及atof函式本身的運作原理很簡單, 其實就是一個一個字元去把數字算出來而已. 下面是一個簡單的atoi函式的過程.
  414. // 模擬atoi函式的運作
  415. #include < stdio.h >
  416. #include < stdlib.h >
  417. #include < string.h >

  418. void main(void)
  419. {
  420.         char string[80];
  421.         int  i;
  422.         int         len;
  423.         int  num;

  424.         gets(string);
  425.         len=strlen(string);

  426.         num=0;
  427.         for ( i=0; i < len; i++ )
  428.         {
  429.                 num*=10;
  430.                 num+=string-'0';
  431.         }
  432.         printf("%d\n",num);
  433. }

  434. sprintf的原理也是一個一個數字把它再換回去成為字元而已, 下面是一個把數字轉回字串的程式
  435. #include < stdio.h >
  436. #include < stdlib.h >
  437. #include < string.h >

  438. void main(void)
  439. {
  440.         char string[80];
  441.         char temp;
  442.         int  i,j;
  443.         int  len;
  444.         int  num;
  445.         scanf("%d",&num);
  446.         len=0;
  447.         do
  448.         {
  449.                 string[len++]='0'+num%10;
  450.                 num/=10;
  451.         }while(num>0);
  452.         string[len]='\0';
  453.         // 字串反轉
  454.         for ( i=0, j=len-1; i < len/2; i++,j-- )
  455.         {
  456.                 temp=string[j];
  457.                 string[j]=string;
  458.                 string=temp;
  459.         }
  460.         printf("%s\n",string);
  461. }

  462. 為什麼會需要用到sprintf?有很多情形下, 不會使用到printf來做輸出. 像是在視窗作業系統開啟一個Message Box來顯示訊息. 此時就需要先把需要輸出的數字都轉成字串, 再透過WIN32 API 函式來秀出訊息.
  463. 範例:開啟一個MessageBox來顯示計算求得的正方形面積
  464. #include < stdio.h >
  465. #include < windows.h >
  466. void main(void)
  467. {
  468.         char string[80];
  469.         int  r;
  470.         int  area;
  471.         scanf("%d",&r);
  472.         area=r*r;
  473.         sprintf(string,"Area=%d",area);
  474.         MessageBox(NULL,string,"Hello",MB_OK);
  475.         // Win32 API之一, 會開啟一個簡單的message box, 印出第2個參數的字串內容
  476. }

  477. 那為什麼需要用到atoi/atof?用scanf來讀鍵盤時,使用者可能會輸入錯誤. 例如說要輸入數字卻輸入字元. 比較好的方法就是scanf中讀進去的東西都先把它當成字串, 檢查字串中有沒有不合理的東西出現. 不合理就要求重新輸入, 合理的話才把字串轉成數字.
  478. #include < stdio.h >
  479. #include < stdlib.h >
  480. #include < string.h >

  481. void main(void)
  482. {
  483.         char string[80];
  484.         int  num;
  485.         int  len;
  486.         while(1)
  487.         {
  488.                 printf("Please input an integer:");
  489.                 scanf("%s",string);
  490.                 // 檢查字串中有沒有不是數字的字元出現
  491.                 len=strlen(string);
  492.                 for ( int i=0; i < len; i++ )
  493.                 {
  494.                         if ( string < '0' || string > '9' )
  495.                                 break;
  496.                 }
  497.                 // 如果每個字元都是'0','1',...'9'當中的任一個, 就跳出迴圈
  498.                 if ( i==len )
  499.                         break;
  500.         }
  501.         num=atoi(string);
  502.         printf("I get %d\n",num);
  503. }
複製代碼
您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

本論壇為非營利之網路平台,所有文章內容均為網友自行發表,不代表論壇立場!若涉及侵權、違法等情事,請告知版主處理。


Page Rank Check

廣告刊登  |   交換連結  |   贊助我們  |   服務條款  |   免責聲明  |   客服中心  |   中央分站

手機版|中央論壇

GMT+8, 2026-10-19 04:14 , Processed in 0.032908 second(s), 15 queries .

Powered by Discuz!

© 2005-2015 Copyrights. Set by YIDAS

快速回復 返回頂部 返回列表