千慮一得齋OnLine_觀死書齋-Yahoo/Hexun/Blogger/sina/Xuite

觀死書齋暨Spread、和訊博客全文檢索

2019年7月10日 星期三

C++自修入門實境秀、C++ Primer 5版研讀秀 5/ ~頁56指標(pointer)-20190709_153006





52
3:45 2.3.2
指標(大陸翻「指針」) 和參考一樣,「*」只在定義指標時用,運算時不用。 6:35 windows10語音辨識軟體輸入文字測試 4:18指標(pointer)是一個物件object,而參考(reference)不是! 參考、指標皆似變數variable,唯參考沒有實體對象object,但指標有。 6:00 在生命週期中一個指標可以指向不同的物件 7:45指標因為可以指向數個不同的物件,因此它是複合型別(compound
type)
13:45bedevil 10:20參考定義時即須初始化,而指標不必。 但注意使用未經初始化的物件所會造成的災難!(見頁45上) 20:07 28:20影音又不同步了 取用一個物件的位址(Taking
the Address of an Object
指標要怎麼初始化?大概就是用 &address-of
取址運算子)來作初始設定式(初始器) 指標是對「誰」的指標也是在此初始設定式(initializers)中來指定指向
point to
的。 28:40有物件才有位址,有位址才有指標
pointer
參考不是物件,所以參考沒有位址,就不可能被指標 41:20 可見指標和位址是密不可分的。「指標」的「標」誰的標?指,指向誰?找對主詞 即「位址」的座標,指向「位址」。 除了涵蓋於§ 2.4.2§
15.2.3
的兩個例外,指標的型別和指標所指的物件必須匹配: 50:45 指標值(Pointer
Value
就是位址 53
指標有沒有「效」(valid
or invalid)
,猶如有沒有被初始化一樣地重要! 59:00 未定義的(undefined)都會產生要命、棘手(bedevil)的錯誤 解參考運算子(*
dereference
用解參考運算子來Using a Pointer to Access an Object
we can use the dereference operator (the * operator ) to access that object:
注意是「object」(也就是value),不是位址(大陸翻「地址」)1:10:00 所以以下印出的是42
int ival = 42; int* p = &ival; // p holds the address of ival; p is a
pointer to ival std::cout
<< *p; // * yields the object to which p points;
prints 42 1:18:45
而以下印出的是「0073F8BC0073FB70
0073FAC8……
」這些記憶體位址: int ival = 42; int* p = &ival;
std::cout
<< &p; 位址(地址)誰的位址?
找對主詞 記憶體位址1:29:00
Dereferencing a pointer yields the object to which the pointer points. We can
assign to that object by assigning to the result of the dereference:   1:35:05 Key
Concept: Some Symbols Have Multiple Meanings
找對主詞 添字還原 C++ 有些 符號, 具有 多樣的 意義 分辨
& *
用到的地方,就決定了它的作用,如在VBA
&
*的用法就與C++截然不同。對錯問題,回到二作!九陽神功第9招! 1:41:40參考可指定的值(不能是定數值,也不能是運算式的結果;須是物件變數)
Some symbols, such as & and * , are used as both an operator in an expression
and as part of a declaration. The context in which a symbol is used determines
what the symbol means:
對錯問題,回到二作
context
先抓動詞 determines 找對主詞 the context Because the same
symbol is used with very different meanings, it can be helpful to ignore appearances
and think of them as if they were different symbols. ignore appearances1:54:30
就是「離相,不著文字相的」意思。把
& *
這兩個符號用在不同context時,看作成不同的符號,不要認為它都長得一樣。
think of
就好像禪觀、照見,即所謂的佛眼、法眼。 2:1:12 54
Null
指標(Null
Pointers
空值指標 如何判斷一個指標是否為「null」值 2:11 英文版Visual
Studio
「實體」是翻自「entity 2:28:20(影音又不同步!)「cstdlib」怎麼斷句?c.std.lib!
preprocessor2:32:40
翻成前置處理器 這個「器」和「初始器」的器一樣,不是CPU
那個東東,而是一段程式碼或程序的意思。 所以可以翻成「前置處理程序」,所以原文才說「the
preprocessor is a program
」: We’ll describe the preprocessor in a bit more
detail in § 2.6.3 (p. 77 ). What’s useful to know now is that the preprocessor
is a program that runs before the compiler.
參考: C/C++杂记:NULL0的区别、nullptr的来历 2:39:50 Forvo網站可以聽取發音
It is illegal to assign an int variable to a pointer, even if the variable’s
value happens to be 0 . Click here
將一個int變數指定給一個指標是不合法的,即使那個變數的值剛好是0也一樣。
int zero = 0; pi = zero; //
錯誤:無法將一個int指定給一個指標 2:53:25因為「指標」和「位址」是分不開的,不能指定值或含一般型別的變數給指標,應該是要給一它一個「位址」,所以需要取址運算子「&」,就像不能在定義時指定「值」給參考一樣。(頁51
int* p1 = nullptr; int v=0; p1 = v;
嚴重性 程式碼 說明 專案 檔案 隱藏項目狀態 錯誤
(
作用中)
E0513
類型
"int"
的值無法指派至類型 "int *" 的實體 prog1 C:\Programming\prog1\prog1\prog1.cpp 13 如果改成:
int* p1 = nullptr; int v=0; p1 = &v; 2:58:40
就可以了。當我們:
std::cout
<< p1; 出來的就是位址,而 std::cout <<
*p1;
出來的就是0(這個值)。 看妳需要的是指標指向物件的位址的值,還是指標指向物件的值。 3:6:00 建議:Advice:
Initialize all Pointers As with any other uninitialized variable, what happens
when we use an uninitialized pointer is undefined. Using an uninitialized
pointer almost always results in a run-time crash. However,……
用了一個沒有經過初始化的指標將會是執行期間的大災難。
If possible, define a pointer only after the object to which it should point
has been defined.3:15:05
先抓動詞 找對主詞 has been
defined the object it should point a pointer
關係代名詞which
找對主詞 the object3:19:00(影音又不同步!) which是代「the object」。是後位修飾。 55
3:27:10 Assignment
and Pointers


指標和參考二者都提供了對其他物件變數(object)的間接存取方式(indirect access to)。然而二者卻有極為不同的方式來進行此種間接存取。最大的不同就在於參考並不是一個物件。一旦我們定義了一個參考,就沒辦法再用這個參考去參考別的(different)物件了。當我們在用一個參考時,我們總是在操作那個在我們定義參考時就被繫結到(initially bound)這個參考的物件。 然而在一個指標與它所指向(holds)的(記憶體)位址之間並不存在上述的關係。就像對其他任何一個非參考類型的變數((nonreference)variable)的操作一樣,當我們指定一個值給指標時,3:38:30我們就賦與了那個指標一個全新的值(舊值會被抹去)。一個指定指標值的行為,就等於將那個指標指向了另外一個不同的物件:3:43:00 pi2 initialized to
hold the address of I
在初始化pi2的同時,pi2取得了i這個 int型別變數的所在位址。
pi2 now addresses
no object
先抓動詞 addresses 經過pi2=0這樣的指定後,pi2現在就沒有指向任何的物件。3:46:30(影音又不同步!) pi2等於是歸零,未初始化了。 對於指標指定一個值的操作,很難確定這樣的指定到底是改變了那個指標的值,還是那個指標所指向的物件。(可是呢參考就一定是與他參考的物件連動的!)3:54:50 It can be hard to
keep straight……
沒有規則可循的
straight 條理 keep straight 井井有條、有條不紊 即使如此,有一點我們必須要牢記在心的就是,一個指定值(assgnment)的操作,就是在將等號(=)左邊的運算元改變它的值。(就是在改變符號左邊的運算元) *pi=0; 4:5:20
(影音又不同步!)因為「*」是解參考運算子,所以0是設定(assign)給pi解參考後的對象(object,在這裡是ival),而不再是對pi,當然piunchanged int* pi = nullptr; int ival=2; int* pi = &ival; pi = 0; std::cout << ival<<"\n"<<pi; 4:11:40這樣pi列印出來就是「00000000」(歸零)4:18:00(影音不同步!)可是ival仍是2 可是這樣: int ival=2; int* pi = &ival; *pi = 0; std::cout << ival<<"\n"<<pi; 印出來的就是: 0 0076F758 4:24:20 pihold的位址不會變,但值會隨著它指向的ival改變。ival由初始2,改成了0 4:30:20 Other Pointer
Operations
其他的指標操作/運算
Two pointers are
equal if they hold the same address and unequal otherwise.
(
指標所載hold)位址相同,則指標值相同。
or if they are both
pointers one past the same object. Note that it is possible for a pointer to an
object and a pointer one past the end of a different object to hold the same
address. Such pointers will compare equal.
或它們都是超出相同物件一個位置的指標,那麼兩個指標就持有相同的位址(即相等)。請注意,指向某個物件的一個指標,以及超出另一個物件尾端一個位置的指標可能存有相同的位址,這樣的指標比較起來會相等。
4:45:20此句中譯似有問題。尤其「超出」二字。 可見相同的pointer(指標)未必是指向相同的物件。而可能只是剛好它的位址有連接到或重疊罷了。 56 4:52:20 Using an invalid
pointer as a condition or in a comparison is undefined.
用無效的指標來進行條件式的判斷或比較運算,是毫無意義的。
怎麼可以翻成「是未定義的」? 哪有照字面翻都不管中文意含的,那麼用中文的誰看得懂到底在說什麼、要說什麼。 有「被定義的」(defined)當然就是「有意義」的囉;那麼「沒被定義的」(undefined)不就是「沒有意義」了嗎?所以可以翻成中文的「毫無意義」來加強語氣也。4:56:15 翻譯學,中文能不好嗎?! void* 指標(void* Pointers void*型別的指標是一種特殊類型(type)的指標,這種類型的指標可以承載(hold)任何物件的位址。5:0:35(可以指向任何物件的位址)像其他的指標,這種類型的指標只承載(記錄)了該物件的位址,至於該物件的型別(type)是什麼,則無法得知。(就是沒辦法逆推回去、藉由指標得知所指物件的型別) 這個void只不過是把前面指定基礎型別的關鍵字(如intdouble5:5:50改成「void」而已嘛!就像寫函式的回傳值一樣。 5:14:00 懷疑原文「void* Pointers」的星號asterisk是誤植。當省略「pointer」的時候,「*」才有必要保留,表示所述的乃是一個指標;或作為指標的標記。如此句中的用法:5:21:20 We cannot use a
void* to operate on the object it addresses—we don’t know that object’s type,
and the type determines what operations we can perform on the object.
對於void*指標我們能做的事很有限。 指標和「pass」的關係要注意! we can pass it to
or return it from a function,
5:17:00 我們可以將這樣的指標傳給一個函式或從函式中傳回它來。 pass在這應是把它的值傳給一個函式的意思。 記憶體memory這個元兇終於出現了,所以address必然是與它脫不了干係的嘛 5:25:45 物件object、指標pointer、記憶體memory 這三角關係 練習2.18 Write code to change the value of a pointer double ival = 2.22,*pi=&ival,dval=3.3; pi = &dval; 5:38:00 指標就像改嫁(可以改代入的對象,換人做做看);而參考就是從一而終,不能改嫁入的對象object。(剛好是練習2.19的答案之一)指標也像女性受孕。只是void*這種,可以接受任何型的,而非void*則可接受指定或者限定型的任何一個。 Write code to
change the value to which the pointer points
double ival = 2.22,*pi=&ival,dval=3.3; *pi = 2; 5:43:00 二題關鍵只差在一個「*」(解參考運算子)上。 練習2.20 int i = 42; int* p1 = &i; *p1 = *p1 * *p1; 5:50:10結果就是 i變成了42的平方(42×42)而p1的值(hold住的位址)沒變 練習2.21 int i=0; double *dp =&i;//不合法,因為用來初始化的idp型別不同。 int*ip=i;//illegal,because
i is not an address.
5:54:40 int*p=&i;//legal,because
using address-of operator “&” before the i.
改成以下便可:
int i = 0; void* dp = &i; int* dpp = &i; int* ip = &i; int* p = &i; 練習2.22 5:59:00(影音不同步!) if(p)//只要p不是NULLnullptr0,且是valid的,就恆真true if(*p)//只要*p!=0,就恆真 練習2.24 6:10:30 因為pvoid*,可接受任何型的;而lp卻是 long,與i int型別(type)不同,所以illegal. 57 2.3.3. Understanding Compound Type Declarations 6:13:26影訊提早結束,音訊未結束。影音不同步!