共筆
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    6.C Arrays === ## 6.1-6.3 Defining Array ### Array(陣列): 一群具有相同資料型別及名稱的連續記憶體位置群組 - 示意圖: ![](https://i.imgur.com/oVXPeZU.png) ### 1.陣列的變數定義 - 元素資料型態 陣列變數名稱[元素個數]; ```c= int big_duck[10]; ``` >變數名稱=記憶體位置 ```c= printf("%p", array);//取array第一個元素位址 printf("%p", &array[0]);//跟上面相同結果 ``` ### 2.初始值 - 給定房間數 ```c= int big_duck[10]={1,2,3,4,5,6,7,8,9,10}; ``` - 不給定房間數,但給定人數 ```c= int big_duck[]={1,2,3,4,5,6,7,8,9,10}; ``` 以上兩種方式皆能開啟10個房間, 後者是依據你給了幾個人頭,去決定要給你幾個房間 - 初始值為0 ```c= int big_duck[10]={0}; ``` 若要將整個陣列初始為0,只要將第一個元素設為0就好,剩餘的元素在初始值沒補滿陣列的時候會自動補0 >==但有些時候因編譯器之間的差異,並不會完全補0,debug的時候可以檢查陣列裡是不是都是0== ` 小蜜蜂6.1:不要忘了為應該初始化的陣列指定初始值 ` ` 小蜜蜂6.2:在陣列初始值上提供比房間還多的初始值是一種語法錯誤 ` >e.g.int var[2]={1,2,3}-error - 位置編號(position number) 電腦是以0為起始點,與人類習慣的以1為起始點不同, 所以{元素1}會存在房間[0] ```c= int big_duck[10]={1,2,3,4,5,6,7,8,9,10}; //big_duck[0]=1, big_duck[9]=10 ``` ### 3.索引與運算子優先原則 ```c= var[5+7] ``` - []內的位置編號正式名稱為索引(index)或下標(subscript), ==索引必須為整數或整數運算式== - []是C的運算子,其優先順序與函式呼叫運算子()一樣是**最高** |排名|運算子| 型別| |:--:|:--|:--:| |1|[],()|最高| |2|+, -|加法| |3|<,<=,>,>=|關係| |4|==,!=|相等| |5|&&|AND| |6||||OR| |7|=, +=, -=...|指定| 以上整理自原文書p.248一些重要的比較 ### 4.陣列用途 - **取代多個變數定義** >假設今天想設變數來儲存五位同學的英文和國文成績,一般而言我們會直接逐一變數定義 ```c= int aEn, bEn, cEn, dEn, eEn;//English int aCh, bCh, cCh, dCh, eCh;//Chinese ``` >若開陣列的話,就只要兩個變數定義就好 ```c= int En[5], Ch[5]; ``` 這樣不僅增加程式的可讀性,在6.4的部分也會介紹陣列的變數定義使其可以簡化多行的程式碼 - **循序存取** 以6.4.1為例 ## 6.4 Array examples ### 1.以迴圈初始化陣列 >一般而言,我們要初始多個變數值的話,要這樣一一列出 ```C= int a=1,b=2,c=3,d=4,e=5; ``` >但如果是陣列,可以直接開一個迴圈下去搞 ```c= int grade[5]; for(int i = 0; i < 5; i++) { grade[i]=i+1; } ``` ~(雖然這個例子感覺沒有比較簡潔,但如果是超多變數定義的話,簡潔度就會噴出來ㄌ)~ ### 2.#define 符號常數來指定陣列大小 ```c= #include<stdio.h> #define SIZE 5 ``` - ==**Symbolic Constant(符號常數)**== - 符號常數是一種識別字,當程式進行前置處理時,所有出現符號常數SIZE的位置都會代換成++代換文字++5(replacement text) - 利用符號常數來指定陣列大小,可使程式更具**可修改性(modifiable)** ```c= #include<stdio.h> #define SIZE 5 //可改成10,20,1000等,就不用更改第6和7行的數值了 int main() { int s[SIZE];//s[5] for(int i = 0; i < SIZE; i++)//i < 5 { s[i] = i+1; } return 0; } ``` ` 小蜜蜂6.3:不可在#define前置處理器命令後加上分號,前置處理器命令並不是C敘述式 ` - [ ] #define SIZE 5; ~(所有SIZE位置都會被替換成5;)~ - [x] #define SIZE 5 ` 小蜜蜂6.4:不可將數值指定給symbolic constant,會造成語法錯誤 ` ` 工程師觀點6.1:推薦使用symbolic constant來定義每個陣列大小,使程式更具modifiable ` ` 良好習慣6.1:使用全部大寫字母來命名symbolic constant,以提醒自己symbolic constant不是一般的變數 ` ```c= #define SIZE 5 #define STUDENT 5 ``` ` 良好習慣6.2:在多個字組成的symbolic constant中,以底線_來分開每個字 ` ```c= #define SIZE_STUDENT 5 ``` ` 小蜜蜂6.5:不可存取一個超出陣列範圍的元素(我不知道跟小蜜蜂6.2差在哪QQ) ` ` 除錯技巧6.1:陣列的索引不能<0但要<陣列元素個數,在迴圈繼續條件中加入上述檢查 ` ## 6.5 Character Array; Manipulate Strings ### 1.初始字元陣列 ```c= char string1[] = "first"; ``` ```c= char string1[] = {'f', 'i', 'r', 's', 't', '\0'} ``` 以上兩種宣告是相同的,注意前者"first"裡自動包含一個'\0'空字元(null character), 因此陣列string1實際包含6個字元,==C的所有字串都會以'\0'作為結束==,如後者的形式。 (p.s. 如果要得到一個字串長度可以用sizeof) ```c= char str[]="12345"; printf("%d",sizeof str); //會輸出6,然後str[5]='\0',str[4]='5' ``` ### ==2.scanf至字元陣列== ```c= char string2[20];//一個最多能塞19個字元+1個空字元的陣列 scanf("%19s", string2); ``` - **使用%Xs做字元轉換詞**: %19s使scanf最多讀入19個字元,就不會有使用者輸入20個字元以上,造成緩衝器溢位(buffer overflow)的問題了 - **字元陣列在scanf裡不需在變數名稱前加&**,除非你是要特地讀入某個位置的字元陣列 ```c= scanf("%c", &string2[5]); ``` ~(但因為只讀入一個’字元‘,所以要用%c)~ - scanf會一直讀入字元,直到遇見==空白、tab、newline或EOF==為止 >使字元陣列能放得下鍵盤所鍵入之字元是你的責任! >且要注意是否考慮到了空字元的空間 >(p.s.如果要讀入一整行包括空格&換行的話可以用gets(陣列名字)) >(p.s.getchar()是讀入字元,不論空格) ### 3.printf出字元陣列 ```c= char string2[20]; printf("%s\n", string2); ``` - **轉換指定詞:**%s - 如同scanf,printf不會檢查字元陣列有多大,只會一路印印印,直到遇見**結束空字元**為止。 ## 6.6 Static Local v.s. Automatic Local ### 靜態區域陣列Static ```c= static int array1[3]; ``` - **記得**上一次呼叫後的數值結果 - 若未明確指定初始值,static一律**自動指定為0** ```c= #include<stdio.h> void static_array(void); int main() { puts("第一次呼叫:"); static_array(); puts("\n第二次呼叫:"); static_array(); return 0; } void static_array(void) { static int array1[3]; puts("初始值:"); for(int i = 0; i < 3; i++) { printf("array1[%d]=%d\t",i, array1[i]); } puts("\narray1[i] + 5:"); for(int i = 0; i < 3; i++) { printf("array1[%d]=%d\t", i, array1[i]+=5); } } ``` ``` Output--- 第一次呼叫: 初始值: array1[0]=0 array1[1]=0 array1[2]=0 array1[i] + 5: array1[0]=5 array1[1]=5 array1[2]=5 第二次呼叫: 初始值: array1[0]=5 array1[1]=5 array1[2]=5 array1[i] + 5: array1[0]=10 array1[1]=10 array1[2]=10 ``` >==static原本的解釋是靜電== >[name=佐任] ### 自動區域陣列Automatic ```c= int array2[3]={0}; ``` - **不記得**上次呼叫結果 - **要給定初始值**,不像static,沒給就指定給0 ```c= #include<stdio.h> void auto_array(void); int main() { puts("第一次呼叫:"); auto_array(); puts("\n第二次呼叫:"); auto_array(); return 0; } void auto_array(void) { int array2[3]={0}; puts("初始值:"); for(int i = 0; i < 3; i++) { printf("array2[%d]=%d\t",i, array2[i]); } puts("\narray2[i] + 5:"); for(int i = 0; i < 3; i++) { printf("array2[%d]=%d\t", i, array2[i]+=5); } } ``` ``` Output--- 第一次呼叫: 初始值: array2[0]=0 array2[1]=0 array2[2]=0 array2[i] + 5: array2[0]=5 array2[1]=5 array2[2]=5 第二次呼叫: 初始值: array2[0]=0 array2[1]=0 array2[2]=0 array2[i] + 5: array2[0]=5 array2[1]=5 array2[2]=5 ``` ` 小蜜蜂6.6:static的值不像auto一樣,每次呼叫都會清除至初始值,不要搞混! ` ## 6.7 Passing Arrays to Function ### 1.函式呼叫陣列 #### 呼叫整個陣列 - 傳參考呼叫(**call by reference**): 將陣列第一個元素==位置==及==大小==傳至函式 ```c= void function(int b[], int size);//函式原型 function(array_name, array_size);//函式呼叫 ``` >**陣列名稱**即此陣列**第一個元素位址** >函式得到陣列第一個元素位址後,再依後面給的陣列大小,即可找到整個陣列 >函式內b[]**不需指定大小** ~(可以跑跑看原文書p.264的程式,驗證陣列名稱是否是其第一個元素位址)~ #### 呼叫一個陣列元素 - 傳值呼叫(**call by value**): 將元素的==數值複製==一份給函式 ```c= void function(int x); function(a[3]); ``` #### const(常數)(唯讀) - 用途:避免呼叫函式更改陣列的值 >看到傳參考呼叫的例子,我們是得到陣列的位址並直接對原始元素值進行動作、修改,在很多種狀況下,函式不可以更改陣列中的元素,const就用於此種情況 ```c= void function(const int b[]) { b[0] /= 2;//error b[1] /= 2;//error } ``` >函式中每個嘗試修改此陣列元素的動作都會導致編譯器錯誤 ## 6.8 Sorting Arrays #### 氣泡排序(bubble sort/sinking sort) - 想像成打擂台,從第一關開始打,打贏就換位子,打輸就固定位子,換下一人挑戰 > 課本p.267 ## 6.10 Searching Arrays - 從陣列中搜尋是否有一個符合**關鍵值(key value)** 的數值 #### 線性搜尋 $O(n)$ - 從第0個元素==逐一比較==(檢查)至找到為止~(可能到最後一位)~ #### 二分搜 $O(log n)$(要會ㄟ) - 前提:元素**已排序**過 - 搜尋方法:每搜尋(比較)一次,就==排除一半的元素==不考慮 >先找出陣列的==中間元素==並與key做比較,若x>key就捨棄下半部,搜索上半部,反之亦然,以此類推 - 任何一個陣列的**最大比較次數**,可以由大於此陣列元素個數的第一個2的==次方數==來決定 >課本p.273 ## 6.11 Multidimensional Arrays ### 二維陣列(==Row Major==) - 多重索引:第一個索引為**列(row)**,第二個為**行(column)** ![](https://i.imgur.com/gblzwxu.png) ` 小蜜蜂6.7:不要把a[x][y]寫成a[x,y],這是個邏輯錯誤,電腦會將其視為a[y](逗號被視為運算子) ` >把二維陣列想像成是一棟大樓。先放樓,再放房。 >[name=佐任] ```c= b[樓][房]; ``` ### 初始值 ```c= int b[2][2]={{1, 2}, {3, 4}}; //b[0][0]=1 b[0][1]=2 b[1][0]=3 b[1][1]=4 //內部一個{}表一個子串列,{1,2}在第一列,{3,4}在第二列 ``` - 如同一維陣列,若初始值沒補滿陣列,就會補零,同樣的要檢查是不是真的有補0 ```c= int b[2][2]={1,2,3}; /* 第一列:1 2 第二列:3 0 */ ``` - 若子串列沒有加大括號,則數值會先塞滿第一列,接著塞第二列,空缺補0 ## 6.12 Variable-Length Arrays ### 可變長度陣列 - 使用於在編譯時期還==不知道陣列大小==的情況 ```c= #include<stdio.h> int main() { int arraysize;//儲存陣列大小的變數 scanf("%d", &arraysize);//輸入你想要的大小 int array[arraysize];//宣告陣列 printf("sizeof(array) yields array size of %lu bytes.\n", sizeof(array));//檢驗陣列是否如自己所設的空間一樣 return 0; } ``` ``` Output-- 6 sizeof(array) yields array size of 24 bytes. ``` - 注意到輸入的大小為6,輸出的大小卻是24。 這是因為我們陣列的資料型態是int,**int佔用了4個位元組**,所以開了6個int房間=6*4=24 (p.s.有時候會因為編譯器的問題產生錯誤) # Chapter 6 結束 ###### tags: `程設好難` `學校門口大樹石頭下` `他的課就很好睡阿` <style> .navbar-brand::after { content: " × 老葉的程式設計"; } </style>

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully