台灣最大程式設計社群網站
線上人數
694
 
會員總數:244224
討論主題:188566
歡迎您免費加入會員
討論區列表 >> C/C++ >> 自訂函數錯誤(分段輸出) 急!
[]  
[我要回覆]
1
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
自訂函數錯誤(分段輸出) 急!
價值 : 50 QP  點閱數:405 回應數:10

樓主

DANNY
初學者
60 6
180 26
發送站內信


只能印出前4個字元,我哪裡做錯了嗎?

搜尋相關Tags的文章: [ 自訂函數 ] , [ 分段輸出 ] , [ 錯誤 ] ,
本篇文章發表於2018-03-24 19:43
別忘捐VP感謝幫助你的人 新手會員瞧一瞧
1樓
回應

Raymond
檢舉此回應
任何陣列在傳入函式時都會降格為指標.

當用在函式參數的時候, 等同於.

所以 sizeof(text) 得到的只是指標的大小, 而不是陣列的大小.


本篇文章回覆於2018-03-24 21:15
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
2樓
作者回應

DANNY
檢舉此回應
那要怎麼用成陣列大小?
本篇文章回覆於2018-03-25 09:17
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
3樓
最有價值解答

Raymond
檢舉此回應
>那要怎麼用成陣列大小?

一般來說, 不可能.

在大多數的情況下, 陣列的名字等同於指標, 指向陣列第一個元素的位址: myArray == &myArray[0]. 這是 C 及 C++ 語言的定義.

在 C 及 C++ 語言裡, 陣列大小的資訊不會以隱藏的方式另行存放.

所以不管是 C 或 C++ 語言, 大多數用陣列的函式都會同時傳入陣列的大小, . 唯一的例外是 C-style string (C-型態字串), 因為這個字元陣列是以內容來判斷長度: 以終結字元來決定字串長度.

所以如果你的 Text 陣列裡儲存的是 C-型態字串, 那你不需要傳入 Text 陣列的大小. 你只需要在迴圈檢查 Text[n] 的內容, 到 0 就結束:


註:
[1] 陣列大小或陣列指數最好用 size_t 類型.

[2] 在獨自使用的情況下, 盡量習慣使用前置的 ++ (如上面的 ++i)

[3] 不要用using namespace std. 儘量習慣用 std:: 來前綴所有標準函式庫裡的名字.

[4] 在有些系統上, 為了效率起見, 沒有斷行的輸出會暫存在 buffer 裡. 在這情況下, 螢幕不會有輸出. 所以你必須用 std::flush 來強迫輸出.

[5] std::endl 包括了 "\n" + std::flush.

如果你真的是用 C++, 可以考慮用 std::string. 當然, 以這個簡單的程式片段來說, 用字元陣列或 C-型態字串指標也許更簡單.


【高級話題】
嚴格來說, C++ 可以用 template 跟 array reference 的方式來傳入陣列大小的:


但這種寫法只適合用在陣列大小剛好是字串長度:

因為如果陣列大小超出字串長度, 你會輸出終結字元後面的亂碼.


本篇文章回覆於2018-03-25 22:34
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
4樓
作者回應

DANNY
檢舉此回應
呃...我想對我可能有點難懂,我C++還沒學超過一年(應該吧,我忘記什麼時候學的了)。
可不可以比較詳細的跟我...解釋一下size_t嗎?
本篇文章回覆於2018-03-26 20:17
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
5樓
回應

Raymond
檢舉此回應
size_t 是個 unsigned integer 類型的別名(即 typedef).

它是編譯器針對目標系統上內建的最大 unsigned 整數類別, 專門用來代表目標系統上任何一個物件(包括陣列, 字串, 等...)在理論上的最大長度或大小.

它是 sizeof 運算子的回傳類型, 也是標準函式庫內, 幾乎所有跟『長度』有關的參數的類型; 它也用來做為陣列指數.

在 32-位元 系統上, size_t 一般是取 unsigned long; 在 64-位元系統上, 一般是 unsigned long long.

因為它是個 typedef, 所以你應該 #include 相關的頭檔. 但因它作為標準函式庫裡使用上相當廣泛的物件, 所以許多頭檔內都會自動的加入這個名字, 像 <cstddef>, <cstdio>, <cstdlib>, <cstring>, <ctime>, <cwchar>.

本篇文章回覆於2018-03-26 23:14
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
6樓
作者回應

DANNY
檢舉此回應
PS:
要怎麼傳入CHAR? 我不知道要怎麼說,見下CODE。

程式可能有誤,但應該了解我的意思。
本篇文章回覆於2018-04-05 17:50
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
7樓
回應

Raymond
檢舉此回應
>要怎麼傳入CHAR? 我不知道要怎麼說,見下CODE。
>char my_text[] = "0123456789";
>output_text("9876543210 %s", my_text);
>程式可能有誤,但應該了解我的意思。

上面的程式片段裡, "0123456789" 及 "9876543210 %" 叫『字面字串』(string literal).

第一個字面字串是用來初始化陣列的, 除了這個用法外, 所有其它出現的字面字串都是指標, 指向字面字串的第一個字元.

但因為 "9876543210 %s" 是用來作為參數傳入函式的, 所以情況比較複雜, 要視 output_text() 是以什麼方式來接收參數的, 如果是 array reference, 那 "9876543210 %s" 就當作是用來初始化陣列參數的:


但如果你是這麼寫

傳入的就分別是字面字串 "9876543210 %s" 第一個字元的位址, 及 my_text 陣列第一個元素的位址 (&my_text[0]).

如果你剛學 C++, 就不要管 template 了. C-style 字串就用指標來處理就好, 因為這是最普遍的寫法, 有最大的通用性.

上面 array reference 的寫法是有侷限的, 因為它是個陣列, 所以你不能傳入指標, 因為指標的層級比陣列低, - 陣列會降格成為指標, 但指標無法升級成陣列.


本篇文章回覆於2018-04-05 23:45
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
8樓
回應

Raymond
檢舉此回應
我建議你目前就不要管 template 及 array reference 這個東西了. 只需記住一個概念: 在使用時, 陣列的名字等於指標, 指向陣列第一個元素 (註: sizeof 除外).

如果 Ary 是個陣列, 那 Ary 等於 &Ary[0] (註: sizeof 除外), , 在概念及語意上它們是完全一樣的. 編譯器會把前者轉為後者, 你可以把前者視為後者的方便寫法.

【註】上述有個例外, 唯一的例外就是 sizeof 運算子. 如果 A 是個陣列, sizeof(A) 會得到陣列所佔記憶體的大小. 但一旦你把 A 用在參數裡, 它就變成 &A[0], 函式得到的也就是個指標.

在有些程式語言裡, 你定義了一個陣列, 陣列的大小及維度會以隱藏的方式跟陣列一齊儲存, 不管你程式有沒有用到這些資料, 從記憶體使用的效率來說, 這是個浪費. C 及 C++ 幾乎不會有什麼隱藏的物件, 你的程式需要什麼, 你就定義什麼.

也就是說, 如果你程式的邏輯需要用到陣列的大小, 那你就要用個物件把它存起來, 如果你的函式需要知道陣列的大小, 那函式就必須加多一個參數, 用來傳入陣列的大小.

本篇文章回覆於2018-04-06 06:26
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
9樓
作者回應

DANNY
檢舉此回應
與陣列型態不同的是,vector記得自己的長度資訊,您可以使用size()查詢vector的元素長度,或是使用empty()測試長度是否為0。
(https://openhome.cc/Gossip/CppGossip/vector1.html)
我自己在查了一下。

謝謝Raymond的指點,祝身體健康。
本篇文章回覆於2018-04-23 17:39
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
10樓
回應

Raymond
檢舉此回應
>與陣列型態不同的是,vector記得自己的長度資訊,您可以使用size()查詢vector的元素長度,或是使用empty()測試長度是否為0

那是因為 vector 是個 class, 它至少有兩個資料成員: 一個是個指標, 用來指向配置出來的記憶體; 一個是 size_t, 用來記錄配置元素的數量.

標準函式庫跟你自己寫的程式沒有什麼不同: 需要紀錄什麼資料, 就用一個物件來儲存.

因為你的程式是處理『字串』, 所以跟你程式有更直接關係的是 std::string class.
本篇文章回覆於2018-04-24 00:08
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
   
1

回覆
如要回應,請先登入.