→ azureblaze: 你寫入的是fackb沒錯啊02/09 16:00
→ azureblaze: const int*b 保證的是不能經由b修改02/09 16:01
※ 編輯: OPIV (114.37.141.187), 02/09/2015 16:05:44
推 purpose: 有的書用遙控器來形容指標或參考,const 加在 b 就只是02/09 17:33
→ purpose: 承諾這隻遙控器的轉台功能被拿掉,轉台鍵按下去也不會02/09 17:34
→ purpose: 通電發生作用。fackb 就是你跑去外面買另一隻遙控器來轉02/09 17:35
推 purpose: 修正一下三樓推文,應該說 const 被加在 *b02/09 17:50
推 TobyH4cker: *b += *fackb; 應該就不能了02/09 22:24
→ adcvc: int const *a和const int *a是一樣的02/09 23:12
小弟還是有一點問題耶......
int main()
{
//*
//* 第一個例子
//*
//* (int const *) = (int *) => OK
//*
int *ip;
int const *icp2ip = ip; //* This is OK
//* 修改 const 的方法:
//* *ip = (int);
//*
//* 第二個例子:
//*
//* (int *) = (int const *) => WARNING
//*
int const *icp;
int *ip2icp = icp; //* This is NOT permitted
//* 修改 const 的方法:
//* *ip2icp = (int);
//*
//* 在第一個例子裡
//* *icp2ip 的值可以被 *ip 更改
//*
//* 在第二個例子裡
//* *icp 的值可以被 *ip2icp 更改
//*
//* 那麼為什麼第一個合法第二個就不行呢?
//*
return 0;
}
※ 編輯: OPIV (114.37.141.187), 02/10/2015 14:00:03
→ adcvc: 根據小弟對指標的淺見 int const *icp沒有給出始值時應該就02/10 14:38
→ adcvc: 抱歉,沒給初始值也沒關係哈哈哈。anyway第一個合法是因為02/10 14:41
→ adcvc: 第一個可行是因為icp2ip是不可改變ip位置內的值的02/10 14:43
→ adcvc: 而第二個不行是因為*ip2icp會改到*icp的值,這樣會違反02/10 14:44
→ adcvc: const int的意義,所以不能這樣使用。02/10 14:44
→ adcvc: 回答得有點亂= = sorry02/10 14:45
沒關係^^
只是,第一個不是還是可以用 *ip = xxx; 來更改 *icp2ip 嗎?
int *ip = (int *)malloc(sizeof(int));
const int *icp2ip = ip;
*ip = 5;
printf("%d", *icp2ip); // 5
*ip = 6;
printf("%d", *icp2ip); // 6
※ 編輯: OPIV (114.37.141.187), 02/10/2015 14:50:32
※ 編輯: OPIV (114.37.141.187), 02/10/2015 14:58:39
推 purpose: 那就還是一樣,指標是遙控器,malloc出來的地方是電視機02/10 14:56
→ purpose: const 限制的始終還是遙控器本身,當 const 在 * 左邊 02/10 14:57
→ purpose: 也只是代表,遙控器被限制成不能把電視轉台,而不代表 02/10 14:58
→ purpose: malloc製造出來的電視機,從此被你鎖住,變成不可更改 02/10 14:59
※ 編輯: OPIV (114.37.141.187), 02/10/2015 15:03:19
感謝 p大!
我好像懂了!
如果把"=" 看做是複製遙控器,那麼複製遙控器就有四種可能性:
1. (int *) = (int *)
2. (int *) = (const int *)
3. (const int *) = (int *)
4. (const int *) = (const int *)
要複製遙控器的時候,不可以用一般的遙控器去複製被鎖定的遙控器,即 (int *) = (
const int *),因為這樣"被鎖定"的特性就漏失了
而 (const int *) = (int *) 則可以理解成是複製了一般的遙控器之後再把它鎖定,這
樣應該是很合理的
所以 (int *) = (const *int) 是不合法的
而(const int *) = (int *) 則是合法的
※ 編輯: OPIV (114.37.141.187), 02/10/2015 15:21:49
※ 編輯: OPIV (114.37.141.187), 02/10/2015 15:25:37
推 purpose: 這種規定很常見,比如 Windows 提供 CreateFile() 函數 02/10 15:26
→ purpose: 你可以呼叫他去到處亂開別人的檔案、設備,然後 OS 傳回02/10 15:26
→ purpose: 的類指標,會看你帳號來給于權限,你的轉型就好像要把02/10 15:27
→ purpose: 本來你只能唯讀的東西,開成有完全控制權限的指標一樣02/10 15:28
糟糕!那我又有新問題了= =
如果照上面這樣講,這句應該是不會有 warning 的才對啊
(int const *const *) = (int **)
但是 clang 居然叫了!!!
※ 編輯: OPIV (114.37.141.187), 02/10/2015 15:57:26
推 RealJack: (int const*const*)=(int **)在g++沒問題,要不要貼個02/10 17:12
→ RealJack: 警告訊息參考一下02/10 17:12
R 大 here you are:
test3.c:6:20: warning: initializing 'const int *const *' with an expression of
type 'int **' discards qualifiers in nested pointer types
[-Wincompatible-pointer-types-discards-qualifiers]
int const *const *b = a;
^ ~
1 warning generated.
剛剛試過了,會 warning 的有
clang test.c
gcc test.c
不會 warning 的有
clang test.cpp
g++ test.cpp
g++ test.c
※ 編輯: OPIV (114.37.141.187), 02/10/2015 18:40:20
推 purpose: C 語言的隱式轉型規則,只有簡單加上一個 const 所以不會02/10 18:59
→ purpose: 變成 const int *const * 但是 C++ 的隱式轉型規則可以 02/10 19:00
→ purpose: 直接把 int ** 隱式轉成 const int *const * 這很安全 02/10 19:01
所以說,我應該要強制轉型囉!?
這樣聽起來意思應該是說 C 的隱式轉型不會自動轉,所以丟 warning 告知你一下,C++
會,所以沒差,是這樣嗎?
那前面的(const int *) = (int *)那些為什麼不需要強制轉型呢?
有沒有什麼資料是關於轉型的規則的呢?
※ 編輯: OPIV (114.37.141.187), 02/10/2015 22:38:50
→ purpose: 所以 int ***p; int ** const*p2 = p; 對 gcc 是完全OK02/10 23:32
嗯嗯 感謝 p 大的幫助
我找到一個把 const 說明得很好的文件
應該對很多人會有幫助
"http://www.dansaks.com/articles/1998-08 What const Really Means.pdf"
※ 編輯: OPIV (114.37.141.187), 02/11/2015 12:04:22