討論區快速選單
知識庫快速選單
討論區最近新進100則主題 網路投保旅行平安險 傑米的攝影旅遊筆記
[ 回上頁 ] [ 討論區發言規則 ]
函式主體的參數陣列大小問題
更改我的閱讀文章字型大小
作者 : kotty123(存在)
[ 貼文 56 | 人氣 0 | 評價 10 | 評價/貼文 0.18 | 送出評價 12 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/20 下午 02:46:01
雖然我可能能力不夠
但我還是想寫一個字串比對函式,之前也有網友建議我去寫寫看

那像是
void vs(char a[],char b[])
{
    
    
}


參數陣列a 跟 b,這樣宣告是正常的嗎?
我沒有寫參數的大小
編譯器有給過

但這個編譯器非常鬆, 我不太放心所以放上來問下

謝謝
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/20 下午 09:54:59
首先, 函式名字跟參數那個部份不叫「函式主體」, 函式的 {...} 部份才叫「主體」.


>雖然我可能能力不夠
>但我還是想寫一個字串比對函式,之前也有網友建議我去寫寫看
>
>那像是
>void vs(char a[],char b[])

字串比對, 難道不用傳回比對的結果!?


>參數陣列a 跟 b,這樣宣告是正常的嗎?

當用在函式參數的時候, T t[] 等於 T *t. 這兩個是語意上是完全相同的.

你不可能直接傳入整個陣列 (除了用 struct 來包, 但這會降低效率), 因為陣列名字在大多數情況下 (sizeof 除外) 是個指標, 指向陣列第一個元素的位址.


>我沒有寫參數的大小
>編譯器有給過
>
>但這個編譯器非常鬆, 我不太放心所以放上來問下

編譯器只有標準的符合「度」, 沒有「鬆」「緊」的問題. 你的是什麼編譯器.

作者 : kotty123(存在)
[ 貼文 56 | 人氣 0 | 評價 10 | 評價/貼文 0.18 | 送出評價 12 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/20 下午 10:38:29
>字串比對, 難道不用傳回比對的結果!?



這部分我有兩個專案,一個是傳回int值
一個就直接printf顯示比對成功之類的







>當用在函式參數的時候, T t[] 等於 T *t. 這兩個是語意上是完全相同的.
>你不可能直接傳入整個陣列 (除了用 struct 來包, 但這會降低效率), 因為陣列名字在大多數情況下 (sizeof 除外) 是個指標,
> 指向陣列第一個元素的位址.

所以這麼宣告是合法的?


再來就是我這樣寫有牽涉到指標?
可是我根本還沒翻到指標...








>編譯器只有標準的符合「度」, 沒有「鬆」「緊」的問題. 你的是什麼編譯器.

 devc++用的是GNU GCC


至於你說的 符合"度" 跟 鬆 緊無關這我不理解
假如該編譯器與標準符合"度"不高, 那不是就有可能更 寬鬆嗎?..
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/21 上午 01:39:58
>>當用在函式參數的時候, T t[] 等於 T *t. 這兩個是語意上是完全相同的.
>>你不可能直接傳入整個陣列 (除了用 struct 來包, 但這會降低效率), 因為陣列名字在大多數情況下 (sizeof 除外) 是個指標,
>> 指向陣列第一個元素的位址.
>
>所以這麼宣告是合法的?

是不是沒有清楚講明『這樣做是合法的』你就不會心安!!? 上面的回覆裡, 『語意上完全相同』難道還不足以表達出『是合法的』這個意思?

你可以寫:
  void f(int *ai) {...}

  void f(int ai[]) {...}
它們是完全一樣的東西.

例子如果不用 char, 你是不是也還不心安 ^^ !?, 那就再重複一次:
  void f(char *s) {...}

  void f(char s[]) {...}
是一樣, 呃, 是合法的!


>再來就是我這樣寫有牽涉到指標?
>可是我根本還沒翻到指標...

  int ai[10] = {...};
  f(ai); /* 傳入的只是指標: &ai[0] */

函式 f() 看到的只是個位址, 指向 ai 第一個元素.

在 C 及 C++ 語言裡, 陣列跟指標雖然是不同的類型, 但它們有非常密切的關係, 你不可能把它們抽取出來分開討論學習.

所有跟陣列指標有關的常見問題, 請自己看
  http://c-faq.com/aryptr/

第一次你可能看不懂, 但務必把這個網站記下來, 你以後會經常用得到.

>>編譯器只有標準的符合「度」, 沒有「鬆」「緊」的問題. 你的是什麼編譯器.
>
> devc++用的是GNU GCC

Dev-C++ 有不同版本, 主要是看它底下的 gcc 的版本.
gcc 倒滿符合標準的, 但你要在 command line option 裡設定, 自己去看 Options Controlling C Dialect 裡的說明:
  https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options

如果沒有這個設定, gcc 會用非標準的 language extension
  https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions

>至於你說的 符合'度' 跟 鬆 緊無關這我不理解
>假如該編譯器與標準符合'度'不高, 那不是就有可能更 寬鬆嗎?..

你的「寬鬆」是不是表示「不該編譯的它可以編譯」? 如果是「該編譯的它無法編譯」呢? 這算「寬鬆」嗎?

作者 : kagaya(kagaya) VC++優秀好手C++優秀好手貼文超過1000則人氣指數超過30000點
[ 貼文 1602 | 人氣 38709 | 評價 4610 | 評價/貼文 2.88 | 送出評價 115 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/21 上午 10:32:59
我記得之前ozzy大大有貼過linux原始碼給你 不知你看過沒?
多看開放原始碼學習
http://www.opensource.apple.com/source/Libc/Libc-262/ppc/gen/strcmp.c
自己每天亂寫 很難進步的
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1044 | 人氣 3227 | 評價 1270 | 評價/貼文 1.22 | 送出評價 28 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/22 上午 10:45:04
除了亂寫還要會除錯,這是學程式很重要的基本功,力口 油!!!
作者 : kotty123(存在)
[ 貼文 56 | 人氣 0 | 評價 10 | 評價/貼文 0.18 | 送出評價 12 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/23 下午 09:15:00
>  int ai[10] = {...};
>  f(ai); /* 傳入的只是指標: &ai[0] */
>函式 f() 看到的只是個位址, 指向 ai 第一個元素.
>在 C 及 C++ 語言裡, 陣列跟指標雖然是不同的類型, 但它們有非常密切的關係, 你不可能把它們抽取出來分開討論學習.
>所有跟陣列指標有關的常見問題, 請自己看
>  http://c-faq.com/aryptr/
>第一次你可能看不懂, 但務必把這個網站記下來, 你以後會經常用得到.






雖說我知道英文對於以後看c函式原型等原文資料很重要
但現在我的英文程度沒辦法看懂


另外我想我可能要回去慢慢看書的指標了
因為我完全聽不懂你說的 "你不可能直接傳入整個陣列" 等等


像是我前幾天寫的一個很爛的字串比對函式
我就有成功把陣列傳進去
而且函式運作好像也挺正常的
這是一個不解



另外還有個狀況
就是在main裡宣告一個 值是4個字元的c字串
sizeof測這c字串是5個字元(byte
但到了函式主體區
我再用sizeof測這c字串, 結果顯示這c字串的byte 變成4個(字元




也就是我要寫一個c字串比對函式是要有指標基礎的
但我卻不懂指標 而且完全不懂



我可能就先暫停了吧...








>你的「寬鬆」是不是表示「不該編譯的它可以編譯」? 如果是「該編譯的它無法編譯」呢? 這算「寬鬆」嗎?




該編譯的它無法編譯 這當然就不算寬鬆啦

一般指寬鬆的定義是, 不該編譯的它可以編譯
而我的寬鬆定義也是這樣
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/23 下午 10:48:48
>雖說我知道英文對於以後看c函式原型等原文資料很重要
>但現在我的英文程度沒辦法看懂

程式語言對英文的要求有別於文學上的英文, 技術文件不需要很多很高深的詞彙, 技術文件要求是精確, 很少會有多重解釋的模糊空間. 看英文的說明文件比文學作品要簡單很多, 沒有你想像中困難. 關鍵處是要習慣說明文件的風格, 這個只能靠多看. 不要等到你認為你英文夠好了才開始, 如果你不熟悉技術文件的寫作風格, 你會覺得很難看得懂, 你會一直認為你英文程度不夠 - 事實上也許只是不習慣而已.

另外, 技術文件的要求是精確, 所以讀的時候要注意細節.


>另外我想我可能要回去慢慢看書的指標了
>因為我完全聽不懂你說的 '你不可能直接傳入整個陣列' 等等
>
>像是我前幾天寫的一個很爛的字串比對函式
>我就有成功把陣列傳進去

你沒有傳入陣列, 你傳入的是陣列的位址.

>而且函式運作好像也挺正常的
>這是一個不解

一維的陣列在使用上跟指標幾乎沒有什麼分別, 這是 C 及 C++ 語言的一個特性. 在類型上它們是兩個不同的東西, 但在使用的語法上看不出來.

>另外還有個狀況
>就是在main裡宣告一個 值是4個字元的c字串
>用sizeof測這c字串是5個字元(byte
>但到了函式主體區
>我再用sizeof測這c字串, 結果顯示這c字串的byte 變成4個(字元

不要用 4 個字元的陣列, 用大一點的, 才看得出來:
  #include <stdio.h>
  void func(char x[])
  {
    printf("%zu\n", sizeof(x));
  }
  int main()
  {
    char a[100];
    printf("%zu\n", sizeof(a));
    func(a);
  }
む注意め如果你的編譯器不支援 "%zu", 用: printf("%lu\n", (unsigned long)sizeof(x));

當你在 main() 的時候, 'a' 還是陣列, sizeof(a) 會得到陣列的大小 (單位是 byte).

當你把 'a' 傳入函式的時候, 你傳入的只是 a 的位址, sizeof(x) 得到的只是指標的大小.


>該編譯的它無法編譯 這當然就不算寬鬆啦
>
>一般指寬鬆的定義是, 不該編譯的它可以編譯
>而我的寬鬆定義也是這樣

所以我才說編譯器不應該說「寬鬆」, 因為「符合度」所涵蓋的意義大於「寬鬆」.

作者 : kotty123(存在)
[ 貼文 56 | 人氣 0 | 評價 10 | 評價/貼文 0.18 | 送出評價 12 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/24 下午 10:34:59
>不要用 4 個字元的陣列, 用大一點的, 才看得出來:
>  #include <stdio.h>
>  void func(char x[])
>  {
>    printf('%zu
', sizeof(x));
>  }
>  int main()
>  {
>    char a[100];
>    printf('%zu
', sizeof(a));
>    func(a);
>  }
>む注意め如果你的編譯器不支援 '%zu', 用: printf('%lu
', (unsigned long)sizeof(x));
>
>當你在 main() 的時候, 'a' 還是陣列, sizeof(a) 會得到陣列的大小 (單位是 byte).
>
>當你把 'a' 傳入函式的時候, 你傳入的只是 a 的位址, sizeof(x) 得到的只是指標的大小.
>


不太理解
假如某陣列傳入函式時,是個地址
但地址不是有很多字元嗎?


那為何在函式主體內
sizeof時只測出4個字元?


另外你給的另一個格式好像照樣不行
關了重開 創專案也沒用
訊息就是
main.c In function `main':
main.c stray '\161' in program






作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/24 下午 11:01:57
>不太理解
>假如某陣列傳入函式時,是個地址
>但地址不是有很多字元嗎?

位址沒有字元, 這是陣列
  char a[100]

    char
   +---+
  a|   |む0め
   |---|
   |   |む1め
   |---|
   |   |む2め
   |---|
   ∼   ∼
   |---|
   |   |む99め
   +---+

當傳入函式時 func(a) 等於 func(&a[0]), 傳入的是第一個元素的位址. 在函式 func() 內:
  func(char x[])

    char*      char
   +-----+    +----+
  x| *---+--->|    |aむ0め
   +-----+    |----|
              |    |aむ1め
              |----|
              |    |aむ2め
              |----|
              ∼    ∼
              |----|
              |    |aむ99め
              +----+


>那為何在函式主體內
>用sizeof時只測出4個字元?

因為 sizeof(x) 是 sizeof(char*), 在你的系統上, 指標需要 4 個字元的大小來儲存.


>另外你給的另一個格式好像照樣不行
>關了重開 創專案也沒用
>訊息就是
>main.c In function `main':
>main.c stray '\161' in program

本討論區沒有原始碼排版的功能, 當我貼程式時, 如果用普通的空格字元, 討論區顯示時無法看出原始碼的 indentation. 所以我會用「全形空格符號」來顯示原始碼的 indentation. 你得到的錯誤是因為編譯器無法編譯「全形空格」.

用 IDE 把「全形空格」換成普通空格就可以了.

作者 : kotty123(存在)
[ 貼文 56 | 人氣 0 | 評價 10 | 評價/貼文 0.18 | 送出評價 12 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/26 下午 12:06:09
>位址沒有字元, 這是陣列
>  char a[100]
>
>    char
>   +---+
>  a|   |む0め <-------------0元素最左邊的a代表?
>   |---|
>   |   |む1め
>   |---|
>   |   |む2め
>   |---|
>   ∼   ∼
>   |---|
>   |   |む99め
>   +---+
>




0元素最左邊的a代表?











>當傳入函式時 func(a) 等於 func(&a[0]), 傳入的是第一個元素的位址. 在函式 func() 內:
>  func(char x[])
>
>    char*      char
>   +-----+    +----+
>  x| *---+--->|    |aむ0め
>   +-----+    |----|
>              |    |aむ1め
>              |----|
>              |    |aむ2め
>              |----|
>              ∼    ∼
>              |----|
>              |    |aむ99め
>              +----+
>
>
>因為 sizeof(x) 是 sizeof(char*), 在你的系統上, 指標需要 4 個字元的大小來儲存.





所以在fuc呼叫函式中的a, 只是個記憶體內容 是a陣列中0元素地址的變數
所以這個變數,就是指標?




還有
我在自定函式主體內用sizeof測與變數對應的參數,
你說是 在我的系統上,指標需要4個字元大小來儲存
可是我不太理解這一段
假如指標沒有4個bytes呢? 會出錯嗎?

如何看出指標有幾bytes?

還是這裡sizeof(參數)出來的bytes是指標本身的大小
不可超出4bytes ?





抱歉
挺亂的 ....








>本討論區沒有原始碼排版的功能, 當我貼程式時, 如果用普通的空格字元, 討論區顯示時無法看出原始碼的 indentation. 所以我會用「全形空格符號」來顯示原始碼的 indentation. 你得到的錯誤是因為編譯器無法編譯「全形空格」.
> IDE 把「全形空格」換成普通空格就可以了.





聽不懂,是要進編譯軟體後調動什麼?
可是我的都英文介面...
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/9/26 下午 11:41:05
>>位址沒有字元, 這是陣列
>>  char a[100]
>>
>>    char
>>   +---+
>>  a|   |む0め <-------------0元素最左邊的a代表?
>>   |---|
>>   |   |む1め
>>   |---|
>>   |   |む2め
>>   |---|
>>   ∼   ∼
>>   |---|
>>   |   |む99め
>>   +---+
>>
>
>0元素最左邊的a代表?

有沒有看到圖上面的這一行:
  char a[100];

'a' 就是這個句子定義的物件. 上面的圖代表物件 'a' 在記憶體內的樣子.

>>當傳入函式時 func(a) 等於 func(&a[0]), 傳入的是第一個元素的位址. 在函式 func() 內:
>>  func(char x[])
>>
>>    char*      char
>>   +-----+    +----+
>>  x| *---+--->|    |aむ0め
>>   +-----+    |----|
>>              |    |aむ1め
>>              |----|
>>              |    |aむ2め
>>              |----|
>>              ∼    ∼
>>              |----|
>>              |    |aむ99め
>>              +----+
>>
>>
>>因為 sizeof(x) 是 sizeof(char*), 在你的系統上, 指標需要 4 個字元的大小來儲存.
>
>
>所以在fuc呼叫函式中的a, 只是個記憶體內容 是a陣列中0元素地址的變數
>所以這個變數,就是指標?

func() 裡只有參數 'x' 是個變數, 在這個函式裡是看不到 'a' 這個變數名字的. 'a' 是個在 main() 裡的變數, 'a' 這個名字只有在 main() 裡看到.

在程式裡定義了變數, 編譯器會撥出空間來存放它們:
  #include <stdio.h>

  int main(void)
  {
    int i = 100;
    int j = 200;
    printf("&i = %p, i = %d\n", &i, i);
    printf("&j = %p, j = %d\n", &j, j);
  }

在我的系統上, 某一次的輸出結果是:
  &i = 00A8FF18, i = 100
  &j = 00A8FF0C, j = 200

也就是說, 變數 'i' 存放在00A8FF18 這個位址, 變數 'j' 存放在00A8FF0C 這個位址 (傳統上, 位址是用 16 進位來表示, %p 是輸出位址的格式).

           i
          +-----+
  00A8FF18| int |
          +-----+

           j
          +-----+
  00A8FF0C| int |
          +-----+

位址的值並不重要, 它們存放的次序也不重要, 這些都不影響程式的執行. 語言標準沒有規定變數存放的位址, 也沒有規定它們的次序, 編譯器可以根據執行平台的特性來做出最合適的決定.

回到 main() 呼叫 func() 的問題. 當你在 main() 裡呼叫 func() 並傳入 a 時, 編譯器把 a 的位址複製到 func() 的 'x' 裡.

  #include <stdio.h>

  void func(int x[])
  {
    printf("in func...\n");
    printf("&x = %p, x = %p\n", &x, x);
  }
  int main(void)
  {
    int ary[10];
    printf("ary = %p\n", ary, &ary[0]);
    func(ary);
  }

在我的系統上, 執行時的結果如下:
  ary = 00D2F84C
  in func...
  &x = 00D2F778, x = 00D2F84C

main() 裡 ary 的位址是 00D2F84C:
           ary
          +-----+
  00D2F84C∣ int |む0め
          |-----|
          ∼     ∼
          |-----|
          |     |む9め
          +-----+

呼叫 func(ary) 傳入的是 ary 的位址 00D2F84C, 編譯器把這個值複製到 func() 的變數 'x' 裡, 'x' 自己當然也有一個位址 (也就是編譯器撥出來存放 'x' 的記憶體), 'x' 的位址是 00D2F778, 它的內容正式 main() 裡 ary 的位址 00D2F84C:

  func(int xむめ)

             x
            +--------+
    00d2F778∣00D2F84C|
            +--------+

也就是我們俗稱的 (func() 裡的 ) 'x' 指向 (main() 裡的) ary:

  func
-------------------
         x
        +-----------+
00d2F778∣00D2F84C *-+---+
        +-----------+   |
                        |
                        |
  main                  |
-------------------     |
         ary            |
        +-----+         |
00D2F84C| int |<--------+
        |-----|
        ∼     ∼
        |-----|
        |     |
        +-----+

這些東西, 教學的書本都有, 只是用詞遣字也許不同. 討論區不適合作教學用, 你最好是先用課本學習, 有問題先自己去搜尋資料嘗試解決 (學習看英文網站), 最後才在這個做重點發問.


>還有
>我在自定函式主體內用sizeof測與變數對應的參數,
>你說是 在我的系統上,指標需要4個字元大小來儲存

指標也是 C 語言的類型之一, 跟 int, char, float 類型一樣, 有大小, 需要存儲空間.

>可是我不太理解這一段
>假如指標沒有4個bytes呢? 會出錯嗎
如果你把指標看成跟 char, int, float, double 一樣的東西, 你把同樣問題裡的『指標』改成 int:

 『在我的系統上, int 需要 4 個字元大小來儲存, 如果 int 沒有 4 個 bytes 呢, 會出錯嗎』

這個問題有意義嗎?


>如何看出指標有幾bytes?

sizeof()

>還是這裡sizeof(參數)出來的bytes是指標本身的大小
>不可超出4bytes ?

你認為 sizeof(int) 出來的 bytes 是 int 本身的大小不可超出 4 bytes?


>>本討論區沒有原始碼排版的功能, 當我貼程式時, 如果用普通的空格字元, 討論區顯示時無法看出原始碼的 indentation. 所以我會用「全形空格符號」來顯示原始碼的 indentation. 你得到的錯誤是因為編譯器無法編譯「全形空格」.
>> IDE 把「全形空格」換成普通空格就可以了.
>
>聽不懂,是要進編譯軟體後調動什麼?
>可是我的都英文介面...

聽不懂就算了, 反正你的 IDE 跟我的也不一樣, 這也不是 IDE 教學. 自己用 find/replace 把全形空格「 」(在「」裡自己 copy) 以普通空格來取代就好了.

作者 : kotty123(存在)
[ 貼文 56 | 人氣 0 | 評價 10 | 評價/貼文 0.18 | 送出評價 12 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/10/1 下午 04:22:12
>回到 main() 呼叫 func() 的問題. 當你在 main() 裡呼叫 func() 並傳入 a 時, 編譯器把 a 的位址複製到 func() 的 'x' 裡.
>  #include <stdio.h>
>  void func(int x[])
>  {
>    printf('in func...
');
>    printf('&x = %p, x = %p
>...................................
>...............................
>...........................
>....................
>...........
>....
>...

兩個問題問下



1.
幫我檢查我這樣講有沒有錯

在main裡呼叫func()然後傳入a
就等於把a陣列的0元素位址指派給func函式主體中的參數x




2.
想問一下
以下這兩個範例用了不對的輸出格式
所以是不是輸出的都是無意義的亂碼?

 int x;
 printf("%p\n",x);
結果:76E39E34




 int x;
 printf("%d\n",&x);
結果:2686788







另外除了感激,我也想稱讚你的符號繪圖教學法很易懂...



那麼現在我要研究的問題是
為甚麼在自訂函式參數只接到一個從main的陣列的0元素位址情況下
還能存取該陣列其他元素的值












作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/10/1 下午 11:43:37
>1.
>幫我檢查我這樣講有沒有錯
>
>在main裡呼叫func()然後傳入a
>就等於把a陣列的0元素位址指派給func函式主體中的參數x

沒錯.

>2.
>想問一下
>以下這兩個範例用了不對的輸出格式
>所以是不是輸出的都是無意義的亂碼?
>
> int x;
> printf("%p\n",x);
>結果:76E39E34
>
>
>跟
>
> int x;
> printf("%d\n",&x);
>結果:2686788

首先, 'x' 沒有初始化, 所以它的內容是不可預期的. 從 C 語言的角度上, 去存取一個沒有初始化的變數, 是有可能導致不可預期的結果的. 亂碼的輸出是眾多不可預期的結果中, 最好的結果. 在有些系統上, 會有可能造成執行錯誤, 程式當掉.

另外, 如果輸出格式跟相應的變數類型不符, 也是會造成不可預期的結果的. 這也是 printf() 危險的地方.

只要有一個地方會造成不可預期的結果, 那整個程式的執行就是不可預期的. 不可預期的結果包括看似正確無誤的執行.


>那麼現在我要研究的問題是
>為甚麼在自訂函式參數只接到一個從main的陣列的0元素位址情況下
>還能存取該陣列其他元素的值

因為位址 + 1 就會跳到下一個元素, 編譯器會根據指標的類型來計算出下一個元素的位址, 這個就叫做 pointer arithmetic.

  #include <stdio.h>
  int main(void)
  {
    int ary[10];
    int *p = ary;
    size_t n;
    printf("ary = %p\n", ary);
    for (n = 0; n < 10; ++n)
    {
      printf("p + %d = %p\n", n, p + n);
    }
  }

執行的結果:
  ary = 00B8FE88
  p + 0 = 00B8FE88
  p + 1 = 00B8FE8C
  p + 2 = 00B8FE90
  p + 3 = 00B8FE94
  p + 4 = 00B8FE98
  p + 5 = 00B8FE9C
  p + 6 = 00B8FEA0
  p + 7 = 00B8FEA4
  p + 8 = 00B8FEA8
  p + 9 = 00B8FEAC

       int
      +---+
aryむ0め∣   |<-- p
      |---|
   む1め|   |<-- p+1
      |---|
   む2め|   |<-- p+2
      |---|
      ∼   ∼
      |---|
   む9め|   |<-- p+9
      +---+

這個例子的 'p' 就等於之前函式 func() 的參數 'x'.

從 'p' 的角度來看 (或從 func() 的參數 'x' 來看), 已經看不到陣列了. 也就是說, 從指標 'p' 來看, 它根本不知道它指向多少個元素. 所以我常說, 一個指標可以指向一或多個元素. 要知道指標指向的元素有多少個, 只有兩個方法:

1. 根據所指向元素的內容來判斷. 最具代表性的就是 C-字串. 這就是我在另一篇說的: 「字串是特殊內容的字元陣列」. 到這裡, 字串跟指標/陣列的關係就完整的結合起來了.

2. 另一個方法就是在程式裡自己把長度保存起來, 在需要的時候, 一起以參數的方法送入函式裡.

說到指標不得不提一件事, 就是 NULL 指標.

一牽涉到指標就意味著兩個東西: 指標本身的內容跟指標所指向的內容.
  int *p = ...;

'p' 是指標本身的內容, *p 是指標所指向的東西:

    int*
   +-------+
  p|<指標的內容>|
   +-------+

    int*         int
   +-------+    +----------+
  p| *-----+--->| <所指向的東西> |
   +-------+    +----------+

但指標也有可能不指向任何東西. 如果你要把一個指標表示為「不指向任何東西」, 你必須把指標的內容設為 0:
  p = 0;

或是 NULL:
  p = NULL;

NULL 是 0 的代表符號 (#define NULL 0). 兩種寫法都可以, 但習慣上會用 NULL, 因為這提升了程式碼的可讀性.

只要指標不是 NULL, 就表示它指向一或多個可以合法存取的空間. 所以指標一定要初始化, 或盡早設值 (NULL 或指向一個可以合法存取的空間). 如果你意圖透過指標去存取一個不合法存取的空間, 就會導致不可預期的結果.

 板主 : simula
 > C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C++
1 Raymond 13050 
2 青衫 4760 
3 simula 4690 
4 coco 4030 
5 白老鼠(Gary) 3670 
6 ozzy 2540 
7 Ben 2250 
8 Anderson 1960 
9 windblown 1650 
10 Kenny 1560 
C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.2026367