Re: [問題] 13誡之八的疑惑

看板C_and_CPP作者 (殺拉頂)時間11年前 (2014/06/05 06:24), 11年前編輯推噓8(8024)
留言32則, 5人參與, 最新討論串3/3 (看更多)
※ 引述《RealJack ()》之銘言: : ※ 引述《saladim (殺拉頂)》之銘言: : : 小弟對於13誡之八有點疑惑, 主要在第二個敘述, 以下引述第八誡: : : =========== : : 你不可以在一個運算式(expression)中,對一個基本型態的變數修改其值 : : 超過一次以上。否則,將導致未定義的行為(undefined behavior) : (++i)+(i++) : 敘述一是說不可以在一條運算式中對某個變數在不同的地方改變值 : : 你也不可以在一個運算式(expression)中,對一個基本型態的變數修改其值, : : 而且還在同一個式子的其他地方為了其他目的而存取該變數的值。(其他目的 : : 是指不是為了計算這個變數的新值的目的)。否則,將導致未定義的行為。 : 敘述二是說不可以在一條運算式中的一個地方對某個變數改變值, : 又在"同一條運算式的另一個地方"讀取此變數的值 : int i=0; : cout<<i<<" "<<++i<<endl; //未定義,取自C++ primer 5th 簡中版P.123 : 先求++i=> 輸出1 1 : 先求 i=> 輸出0 1 : 敘述一,二會出問題都是因為求值順序未定義 謝謝 這個例子替我解答了部分疑惑 這樣的一個statement的確不是純粹是計算值而已 其實另一個疑惑是 此敘述說不可以因為目的AA(用符號代表) 而在同一個expr 內修改值後再去存取該變數 那我就想問: 那若不是因為AA呢? 若是因為AA就 可以再次存取嗎? 不是目的AA : 為了計算這個變數的新值的目的 或是 其他 ---- (1) AA : 不是為了計算這個變數的新值的目的 ---- (2) (反反邏輯??) 根據(1)(2)跟大大的例子 似乎就有矛盾了 或是: int sum = ++a + a ; // inspired by putumaxally 這就是疑惑之處.........@_@ : : =========== : : 第二個敘述中: "其他目的,是指不是為了計算這個變數的新值的目的" : : 我的疑惑在於, 此敘述似乎暗指 若是為了計算此變數新值的話 仍然可以讀取該變數的值 : : 但是似乎又不合理 因為想不出任何是為了計算變數新值修改到此變數又去讀取的例子 : : 再者, 也會違反八誡的第一個敘述阿?? : : x = x++ * x ; <====這樣算是一個case嗎? ------ (A) : : 也就是說 一般的用法 一個運算式(如同上面的整個式子A)不就是要計算新值的嗎? : : 那不允許在此目的之外修改某變數再去讀取此變數 不就同等於可以這麼做 @_@? : : 搞不清楚阿.............. : : 請各位大大幫忙解惑一下 似乎我有哪邊對於第二個敘述理解錯誤了..... : : 謝謝~~~ 把原文章的推文列在此 ;

06/03 23:55,
敘述二是不是說 sum = a++ + a++; // int a = 0;
06/03 23:55
這個似乎可以用敘述一處理?

06/04 00:18,
不寫入的話,你可以存取該變數無數次;一旦你寫入了,哪怕
06/04 00:18

06/04 00:19,
僅只修改該變數一次,也不能再多做讀取,如:v[i] = i++;
06/04 00:19

06/04 00:20,
即未定義行為。但是 notVarI = i++; 則是有明確結果的運算
06/04 00:20
其實我覺得八誡的整個精神好像可以用pur大說的囊括就可以了 只要寫入過 不論讀取或是再寫入 都會有問題(再寫入也是可能需要再讀取阿~) 只是細讀一下第二敘述又怕哪裡想錯了 想請各路高手幫觧 XDDDD

06/04 01:31,
板上很久沒出現的神人tinlans大大有篇寫得很好
06/04 01:31
感謝 需要時間理解 不過現在無法直接運用阿阿阿阿阿阿 總結: 小魯對於八誡的第二個敘述理解上有些問題(已說明在上面) 對於此誡的精神我的理解是: 只要在同一個運算式修改過變數 則在同一運算式內不論是再讀取或是再修改 皆會有沒定 義的行為出現 似乎此誡的第二個敘述是在說明讀取那方面 只是敘述上有點令人疑惑 不知道是否如此? 煩請各路英雄幫忙 謝謝~~~~~~~~ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.129.21.176 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1401920661.A.2BE.html ※ 編輯: saladim (220.129.21.176), 06/05/2014 06:25:15 ※ 編輯: saladim (220.129.21.176), 06/05/2014 06:26:24 ※ 編輯: saladim (220.129.21.176), 06/05/2014 06:27:39 ※ 編輯: saladim (220.129.21.176), 06/05/2014 06:30:27

06/05 10:50, , 1F
++i; 或 i++; 都自己一行的話,應該就不用管第八戒了
06/05 10:50, 1F

06/05 10:53, , 2F
我寫兩個後置 ++ 你寫成一個前置 ++
06/05 10:53, 2F

06/05 14:16, , 3F
不可以因為AA而... 這句話等同: 因為AA而...是被禁止的
06/05 14:16, 3F

06/05 14:19, , 4F
若是因為AA而...是不行的,標上紅色和綠色的句子是同件事
06/05 14:19, 4F

06/05 14:25, , 5F
誡8可以簡單說: ++a,a++出現過,表達式就'不該'出現a
06/05 14:25, 5F

06/05 14:28, , 6F
像是邏輯&&和邏輯||可以出現a++兩次=> if(a++ && ++a)
06/05 14:28, 6F

06/05 14:29, , 7F
因為求值順序被規定要"先"算左"再"算右
06/05 14:29, 7F

06/05 22:57, , 8F
邏輯判斷要小心 Short-Circuit Evaluation
06/05 22:57, 8F
※ 編輯: saladim (36.228.235.166), 06/06/2014 01:31:53

06/06 02:52, , 9F
RJ 講的正是因為短路的關係所以必須先算左完才能算右
06/06 02:52, 9F

06/06 02:52, , 10F
不過這就代表右邊的計算可能不會進行
06/06 02:52, 10F

06/07 07:51, , 11F
R大 八誡精神我大概理解 只是這邊文字上令人困惑
06/07 07:51, 11F

06/07 07:52, , 12F
然後我有些錯誤 已改 在綠色句子那邊
06/07 07:52, 12F

06/07 07:53, , 13F
修正過後 如果沒再次犯錯的話 才是想要表達的 但這跟R大大
06/07 07:53, 13F

06/07 07:54, , 14F
的解釋文(R大推文的第一,二行)又不太一致
06/07 07:54, 14F

06/07 12:05, , 15F
綠色那段文字 = 誡八敘述一,所以不能再次存取變數
06/07 12:05, 15F

06/07 12:07, , 16F
能否用一個例子指出矛盾點,這樣比較能釐清問題
06/07 12:07, 16F

06/08 20:16, , 17F
R大 就是想不出矛盾例子~ 怎麼說勒 這邊我疑惑之處就是:
06/08 20:16, 17F

06/08 20:17, , 18F
如果不能因為AA作動作BB 那因為AA可以作動作BB嗎?
06/08 20:17, 18F

06/08 21:21, , 19F
文字對照到符號上需要細心檢查,假設AA=下雨,BB=曠課
06/08 21:21, 19F

06/08 21:22, , 20F
第一句:不能因為下雨而曠課,第二句:因為下雨可曠課嗎?
06/08 21:22, 20F

06/08 21:23, , 21F
事實上面兩句子是同一句
06/08 21:23, 21F

06/08 21:25, , 22F
而綠色那句:那若不是因為下雨呢? 是講晴天可不可以曠課
06/08 21:25, 22F

06/08 21:25, , 23F
用r大的例子 第二句就是: 那因為下雨而外的原因可曠課
06/08 21:25, 23F

06/08 21:26, , 24F
其實綠色是講誡8第一條,所以也是不行的
06/08 21:26, 24F

06/08 21:39, , 25F
這個語句我反覆確認過,相信是沒有問題的,這敘述方式和
06/08 21:39, 25F

06/08 21:40, , 26F
所以我是被疑惑了 既然除了少數情況 則修改後讀取跟再修改
06/08 21:40, 26F

06/08 21:41, , 27F
皆不允許 那寫成第二敘述那種形式 會使人想說難道有其他
06/08 21:41, 27F

06/08 21:41, , 28F
這個聯結有一點像(但不是喔) http://ppt.cc/@-,E
06/08 21:41, 28F

06/08 21:41, , 29F
形式可以作修改後再讀取/修改...
06/08 21:41, 29F

06/08 21:42, , 30F
所以 我想第一敘述跟第二敘述只是分別對再修改跟再讀取
06/08 21:42, 30F

06/08 21:42, , 31F
分別說明 對媽? XDDDDDDDDDD
06/08 21:42, 31F

06/08 21:47, , 32F
是的,(先修改再修改)(先修改再讀取)(先讀取再修改)都不行
06/08 21:47, 32F
文章代碼(AID): #1JZvoLA- (C_and_CPP)
文章代碼(AID): #1JZvoLA- (C_and_CPP)