指针的基本操作(10.1 Basic Pointer Operations)
[This section corresponds to K&R Sec. 5.1]
The first things to do with pointers are to declare a pointer variable, set it to point somewhere, and finally manipulate the value that it points to. A simple pointer declaration looks like this:
對指針的第一步操作就是聲明一個指針變量,讓它指向某個地方,最后操作指針指向的值,一個簡單的指針聲明如下:
int *ip;This declaration looks like our earlier declarations, with one obvious difference: that asterisk. The asterisk means that?ip, the variable we're declaring, is not of typeint, but rather of type pointer-to-int. (Another way of looking at it is that?*ip, which as we'll see is the value pointed to by?ip, will be an?int.)
這個聲明看起來非常像我們之前的變量聲明,但是有一個明顯的不同之處,就是那個星號(*),帥帥的星號跟著ip,這個我們聲明的ip變量,不是int類型,它是一個指向整型的指針。(用另一種方法來看這個表達式是,先看*p做一個整體,*p的類型是一個int類型,然后*p分開,把*看到是取地址符號,那ip就是一個指針,也即一個地址,*ip取這個地址的值,這個地址的值是一個int類型)
We may think of setting a pointer variable to point to another variable as a two-step process: first we generate a pointer to that other variable, then we assign this new pointer to the pointer variable. We can say (but we have to be careful when we're saying it) that a pointer variable has a value, and that its value is ``pointer to that other variable''. This will make more sense when we see how to generate pointer values.
我們會想設置一個指針指向另外一個變量要用兩個步驟,首先,我們聲明一個存放在其他地方的變量,然后我們把這個變量的地址賦值給這個指針。我們可以這樣說(但必須注意我們的描述)指針變量保存有一個值,并且它的值是指向其他變量的。這會使得我們對如何生成一個指針變量更加直觀。
Pointers (that is, pointer values) are generated with the ``address-of'' operator?&, which we can also think of as the ``pointer-to'' operator. We demonstrate this by declaring (and initializing) an?int?variable?i, and then setting?ip?to point to it:
Pointers這個指指針的值,通常我們會用到取地址符號(&),當然我們也可以把它認為是“pointer-to”操作。我們聲明一個int變量i,然后把ip指向這個變量i.
ip=&i;這個表達包含兩個步驟,&i是一個指向i的指針,然后把新聲明的指針ip指向這個地方,也即這個指針,這個地址。好了。現在ip就指向了i,我們可以用如下圖示來表示:
i?is a variable of type?int, so the value in its box is a number, 5.?ip?is a variable of type pointer-to-int, so the ``value'' in its box is an arrow pointing at another box. Referring once again back to the ``two-step process'' for setting a pointer variable: the?&?operator draws us the arrowhead pointing at?i's box, and the assignment operator?=, with the pointer variable?ip?on its left, anchors the other end of the arrow in?ip's box.
i是一個整型變量,所以在框框里的是一個數字5,ip是一個指向整型變量的指針,所以ip保存的值是一個地址,并且這個地址保存的是一個整型變量。重新回來看一下兩步操作法:為了設置一個指針變量,&操作取得指向框框里的地址,然后是“=”操作符,把指針變量ip放在左邊,最后重點是i的地址保存在了ip的框框里。
We discover the value pointed to by a pointer using the ``contents-of'' operator,?*. Placed in front of a pointer, the?*?operator accesses the value pointed to by that pointer. In other words, if?ip?is a pointer, then the expression?*ip?gives us whatever it is that's in the variable or location pointed to by?ip. For example, we could write something like
我們發現要取得指針指向的值用(*)操作符,放在指針的前面,(*)操作取得指針指向地址的值,換句話說,如果ip是一個指針,*ip表達式告訴我們ip這個地址的值保存的值是多少,例如,我們可以這樣寫一行代碼:
printf("%d\n", *ip);which would print 5, since?ip?points to?i, and?i?is (at the moment) 5.
當然這會打印5,由于ip指向i,i的值(此時)是5.
(You may wonder how the asterisk?*?can be the pointer contents-of operator when it is also the multiplication operator. There is no ambiguity here: it is the multiplication operator when it sits between two variables, and it is the contents-of operator when it sits in front of a single variable. The situation is analogous to the minus sign: between two variables or expressions it's the subtraction operator, but in front of a single operator or expression it's the negation operator. Technical terms you may hear for these distinct roles are?unary?and?binary: a?binary?operator applies to two operands, usually on either side of it, while a?unary?operator applies to a single operand.)
你一定想知道(*)取地址值的操作,與此同時,他也是乘法操作符。在這里是沒有一點模糊的,乘法操作要具有兩個變量,當它作為取地址值操作符時,它放在變量的前面,它就像減號(-)一樣,當它在兩個變量或者堂之間時,它是減號的功能,當它在一個常量前面時,它被當作負號。這就像一個操作符具有兩種功能,簡單叫它作二次元吧。哈哈!
The contents-of operator?*?does not merely fetch values through pointers; it can also?set?values through pointers. We can write something like
取地址值符(*)不僅僅是取得地址的值,也可以通過這個方法來設置一個地址的值。像下面一樣:
*ip = 7;which means ``set whatever?ip?points to to 7.'' Again, the?*?tells us to go to the location pointed to by?ip, but this time, the location isn't the one to fetch from--we're on the left-hand sign of an assignment operator, so?*ip?tells us the location to store?to. (The situation is no different from array subscripting expressions such as?a[3]?which we've already seen appearing on both sides of assignments.)
這是把ip指向的值設置為7.再次,(*)符號告訴我們它是取得(ip)地址的值的。但是這次,這個地址不是一個取得的值,左邊的表達式(*ip)是取得ip指向的位置。(這就像數組里面的a[3]取得數組里面第2個元素的值一樣)
The result of the assignment?*ip = 7?is that?i's value is changed to 7, and the picture changes to:?
*ip=7這個表達式的結果是把ip這個地址的值變為7.上面的圖改成下面:
If we called?printf("%d\n", *ip)?again, it would now print 7.
我們當然可以用打印來看到*ip的值。它會打印7.
At this point, you may be wondering why we're going through this rigamarole--if we wanted to set?i?to 7, why didn't we do it directly? We'll begin to explore that next, but first let's notice the difference between changing a pointer (that is, changing what variable it points to) and changing the value at the location it points to. When we wrote?*ip = 7, we changed the value pointed to by?ip, but if we declare another variable?j:
int j = 3; and write ip = &j;we've changed?ip?itself. The picture now looks like this:?
指針,我們可能想知道為啥我們寫這么多這么啰嗦。如果我們想把它設置成7.為什么我們不直接操作,我們下面會探討這個,但是首先讓我們注意改變指針的值和改變指向指向位置的值的不同之處。當我們寫*ip=7我們是改變指針指向地址的值的。但是如果我們聲明另一個變量j.
? ? ? ?int j=3;
然后寫
? ? ? ?ip=&j;
我們改變了ip的值,如下圖:
我自己試了一下。要這樣寫才會正確:如果不要int i=8;int *ip=&i;只寫成int*ip;可能會造成ip指向的地方不合法,會出錯。#include <stdio.h> #include <stdlib.h> #include <string.h>int main(void) { int i=8;int *ip=&i;*ip=7;printf("%d\n",*ip);return 0; }We have to be careful when we say that a pointer assignment changes ``what the pointer points to.'' Our earlier assignment
我們一定要注意,當我們說一個指針指向改變的時候,“指針指向什么?”我們先前的分配是這樣的。
*ip = 7;changed the value pointed to by?ip, but this more recent assignment
改變ip指向地址的值,但是我們大多數是這樣聲明的。
ip = &j;has changed what?variable?ip?points to. It's true that ``what?ip?points to'' has changed, but this time, it has changed for a different reason. Neither?i?(which is still 7) nor?j?(which is still 3) has changed. (What has changed is?ip's value.) If we again call
ip=&j通過改變ip來達到改變ip指向的值。它是讓ip指向的值發生了改變,但是這時,它因為另一個原因發生了改變。不是i的值讓ip發生了變化,我們可以再來一次打印。
?
printf("%d\n", *ip);
this time it will print 3.
這時候它會打印出3來。
We can also assign pointer values to other pointer variables. If we declare a second pointer variable:
我們也可以把指針賦值給另一個指針
int *ip2;then we can say
這時我們可以這樣寫
ip2 = ip;Now?ip2?points where?ip?does; we've essentially made a ``copy'' of the arrow:?
這時ip2指向的地方也是ip指向的地址,它本質上只是一個復制操作
Now, if we set?ip?to point back to?i?again:
現在我們把ip又改回i的地址
ip = &i;the two arrows point to different places:?
這時兩個指針指向了不同的地方
We can now see that the two assignments
這時我們可以看到下面兩個表達式
ip2 = ip; and *ip2 = *ip;do two very different things. The first would make?ip2?again point to where?ip?points (in other words, back to?i?again). The second would store, at the location pointed to by?ip2, a copy of the value pointed to by?ip; in other words (if?ip?and?ip2?still point to?i?and?j?respectively) it would set?j?to?i's value, or 7.
是兩個不同的東西。第一個是把ip和ip2是同一個地址。第二種是保存的值,*ip2是ip2地址的值,*ip是ip地址的值,換言之(如果ip 和ip2仍然指向i和j),它會把i的值賦給j.
It's important to keep very clear in your mind the distinction between?a pointer?and?what it points to. The two are like apples and oranges (or perhaps oil and water); you can't mix them. You can't ``set?ip?to 5'' by writing something like
在里心里,指針和指針指向的值你一定要有一個明確的區分,他們兩個就像蘋果和橘子一樣。你一定不能混肴他。你不能把指針賦值5.像下面一樣,是錯誤的。
ip = 5; /* WRONG */5 is an integer, but?ip?is a pointer. You probably wanted to ``set?the value pointed to by?ip?to 5,'' which you express by writing
5是一個整型,但是ip是一個指針,你大概像把ip指向的值設置成5.你可以這樣寫。
*ip = 5;Similarly, you can't ``see what?ip?is'' by writing
你也不能通過這樣來查看ip的值。
printf("%d\n", ip); /* WRONG */Again,?ip?is a pointer-to-int, but?%d?expects an?int. To print?what?ip?points to, use
再說一次,ip是一個指向整型的指針,但是%d期望是整型的,打針ip指向的值,通過下面的打印。
printf("%d\n", *ip);Finally, a few more notes about pointer declarations. The?*?in a pointer declaration is related to, but different from, the contents-of operator?*. After we declare a pointer variable
最后,一小點筆記關于指針聲明,(*)在聲明指針中,但是有區別于操作指針,在我們聲明指針后
int *ip; the expression 下面的表達式 ip = &isets what?ip?points to (that is, which location it points to), while the expression
指導ip指向的值設置為5
*ip = 5sets the value of the location pointed to by?ip. On the other hand, if we declare a pointer variable and include an initializer:
設置ip指向的值,另一方面,我們可以在聲明的時候包含初始化指針的值。
int *ip3 = &i;we're setting the initial value for?ip3, which is where?ip3?will point, so that initial value is a pointer. (In other words, the?*?in the declaration?int *ip3 = &i;?is not the contents-of operator, it's the indicator that?ip3?is a pointer.)
在這里(*)不是說取得ip3指向的值,而是告訴編譯器,ip3是一個指針,然后把這個指針初始化為i的地址
If you have a pointer declaration containing an initialization, and you ever have occasion to break it up into a simple declaration and a conventional assignment, do it like this:
你有一個指針聲明如下,并用第二步來對他進行初始化
int *ip3;ip3 = &i;Don't write
但是不可以這樣寫
int *ip3;*ip3 = &i;or you'll be trying to mix oil and water again.
否則,你又把油和水弄亂了
Also, when we write
當然我們也可以這樣寫。
int *ip;although the asterisk affects?ip's type, it goes with the identifier name?ip, not with the type?int?on the left. To declare two pointers at once, the declaration looks like
*告訴編譯器,后面的變量是一個指針,我們可以像下面一樣來聲明兩個指針
int *ip1, *ip2;Some people write pointer declarations like this:
一些人這樣來聲明一個指針。
int* ip;This works for one pointer, because C essentially ignores whitespace. But if you ever write
它在聲明一個指針是正確的,但是C本質上忽視空格,但是你絕不能這樣寫
int* ip1, ip2; /* PROBABLY WRONG */it will declare one pointer-to-int?ip1?and one?plain?int?ip2, which is probably not what you meant.
他會聲明一個指向整型的指針,和一個整型變量ip2.當然不是你想要的意思
總結
以上是生活随笔為你收集整理的指针的基本操作(10.1 Basic Pointer Operations)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库笔试题 (3)
- 下一篇: java 数据库题,JAVA数据库笔试习