a 2 3 在 C 語言中表達什麼意思?

時間 2021-05-12 00:59:26

1樓:苦盡甘呢

不請自來,當作練習回答。

我們先來看一維陣列,b[n], b 是陣列名字,*b 則可以第乙個元素(整數)的名字,*(b+1) 可以看作第二個元素的名字

同理,a 是二維陣列的名字,*a可以看作第乙個元素(一維陣列)的名字所以 (a+2) 就是第三個元素(一維陣列)的名字等價於 a[2], 指向 a[2] 的第乙個元素 , a[2] +3則是指向陣列的第4個元素的指標,等價於 (a[2] +3) 就等價於 a[2] [3].

2樓:姜哲

其實說到底就是乙個通過計算指標位址求值的問題

陣列a的型別可以退化成 T(*)[3] ,a+2就是這個位址+( sizeof(T[3]) *2),然後對該位址進行解引用 ,*(a+2)得到的型別是 int(&)[3],可以退化到型別T*, 假設x->*(a+2),x是乙個T*,*(x+3)得到得就是乙個T&,通俗來說就是獲取第三行第四列元素的值。

3樓:sin1080

呼叫a的型別的operator +,右手引數是2。

然後呼叫上一步返回型別的operator *。

然後呼叫上一步返回型別的operator +,右手引數是3。

最後呼叫上一步返回型別的operator *。

因為運算子可以過載,所以只能說這麼多了,不知道型別過載了什麼運算子,只能說具體做的是什麼鬼知道。

看錯了,是C,不是C艹,沒有運算子過載。那就簡單了。

a一定是乙個指標的指標,才能*兩次。+就是指標加,加一次實際偏移多少取決於被指向的型別的size。

我們假定a的型別是T**,那麼第一步,向右移2,被指向的型別是T*,於是實際記憶體偏移是平台指標大小(32位平台就是4個位元組,64位平台8個位元組)乘以2。第二步解引用把T*拿出來。第三步再向右偏移3,實際記憶體位址偏移量是3 * sizeof(T)。

最後再解引用拿到被指向的T。

4樓:

初學者剛到多維陣列這裡確實會有點坑……

簡潔的解釋是:

Type a[N][M] 的型別實際上是 (Type[M]) [N] ,當然你不能這樣寫。可以看出它是乙個陣列的陣列,因此在型別系統中它幾乎等同於 Type**。取值的時候需要解引用一次得到 (Type[M]) 型別元素,然後再解引用一次得到 Type 型別的值。

然而我覺得這個解釋太簡潔了……

嘗試從頭說起。(結果就囉嗦得要死

指標是乙個比較直觀的概念,它和整數都有相同意義的加減運算:加法得到這個元素的後繼/前接第幾個元素,減法得到兩個元素之間的間隔。它們的區別在於,指標具有「位置」的含義,它指的是某個元素在記憶體中的位置。

你可以直觀地把指標理解成它的字面意思,想象乙個記憶體布局,乙個指標本身作為乙個整數元素,放在記憶體的某個地方,然後它又意味著記憶體中的乙個「位置」,指向這個布局的另乙個地方,那裡有另乙個元素。

對於乙個序列,或者說一連串元素,也可以想成數列,但一般說陣列,可以用這個序列的最開始的元素的位置(首位址)來代表。為了方便計算,最開始的那個元素叫做第零個元素,第零個元素的位置加一,就是它後面的第乙個元素,第零個元素的位置加N,就是第N個元素的位置。你可以想象乙個指標指向首位址,然後要找陣列的第N個元素的時候它就在首位址後面移來移去。

對於乙個指向陣列首位址的指標 A,A+N就是第N個元素的位址(這還是個位置/指標),*(A+N) 是解引用,代表的才是具體的那個元素的值,一般簡寫為 A[N],兩種寫法沒有區別。

指標指向的元素型別是很重要的:

一是因為,指標加減法的單位是最直觀的「個」,不是位元組。某個具體型別的指標加1,指的是它後面那個元素,而不需要去考慮這個型別有幾個位元組,得到它後面第零點幾個元素。

二是因為,使用指標最終還是為了能夠得到被指向的那個元素,元素是什麼型別,你就會拿到什麼東西,沒型別就沒東西。

指標指向的元素型別可以是一些奇奇怪怪的東西,比如說,指標可以再指向乙個指標

一種直觀的理解是,記憶體布局上有個指標,它指向另一處的某個元素,而那個元素也是個指標,再次指向其他的某個地方。同理,其他的那個地方還可以是個指標,繼續指著某個地方,一直這樣指下去,甚至可以指回最初的那個指標形成乙個環(其實資料結構中的鍊錶就是這個樣子的)。

舉幾個例子會好理解一些。但我為了直觀,沒有用C語言的語法標註型別。

先嘗試看看乙個簡單的型別, int** ,或者分隔一下, (int*) * ,還不好看的話就理解成 (Pointer) *。它是乙個指標,指向的元素型別是 int* 。

對這個指標做解引用,可以得到它指向的元素,於是現在拿到了乙個 int* 型別的值。這個值又是個指標,於是再解引用一次,拿到了 int 型別的值。

雖然很想說解引用一次就少個星號,但標準C的畫風是這樣的:

int**

ppA=

SomePointerOfPointer

;int*pA

=*ppA;

intA=*

pA;//A

==**

ppA;

熟悉完實際寫法之後,繼續看個有點相似的型別, (int*) [N] 。它的標準寫法是 int *A[N] ,A是變數名。

顯然它是乙個陣列,陣列有N個元素,其中每個元素的型別是 int* (指向 int 的指標)。

這時候A也是個指標,雖然實際對應的是個陣列。它指向陣列的首位址(第零個元素的位置)。可以直接對A解引用,得到它指向的首個元素的值;或者取它後面第m個元素的值, *(A+m),簡寫為 A[m]。

從陣列中取出的值 A[m] 還是個指標,想要 int 數值的話,需要再解引用一次,即 *A[m] 。

真實畫風是這樣的:

int*

apA[N]

=;int*pA=

apA[1];

// = *(apA + 1)

intA=*

pA;//=

*apA[1

]=**(

apA+1)

=*(*

(apA+1

)+0)

=apA[1

][0]注釋中的寫法都是完全等價的。是的,指標可以當陣列用的。(身後感到壓力

現在回到最初的問題。我感覺大佬們如果看到了這裡,已經是非常地想錘我了。

對於型別 (int [M]) [N] ,理解與上面是類似的。它的標準寫法是 int A[N][M] 。

它是個陣列的陣列。可以理解成乙個矩陣,也可以說它是乙個有N條元素的大陣列,N個裡的每乙個元素又是一條陣列。

同樣的,A是個指標,它指向N個元素陣列的首個元素,對A解引用得到第n個元素的值;而這個元素的型別又是個陣列(共M個元素),於是再次解引用,得到這個子陣列第m個元素實際的整數值。

所以畫風都沒必要展示了, 跟上面一毛一樣,A[n][m] 完全等價於 *(*(A + n) + m)

但是它的坑在於,前面的兩個例子都是實實在在的兩次跳轉,唯獨它不是兩次跳轉

對於 int **A 或者 int *A[N] ,A 或者 A+n ,是真的指向某個 int* 型別的變數,在它指向的那個位址上, *A 或者 A[n] 真的就放著那個指標變數的數值。解引用兩次,是真的從A跳到這個指標上,拿到這個指標之後,再跳轉一次。

其原因是,多維陣列的結構是乙個連續的整體,即使人為地劃分為多維,但它實際上還是乙個連續的序列,不需要也無法為每個維度儲存乙個指標。例如型別 ((int [2]) [3]) [4] ,結構是這樣的:

intA[4

][3][2

]=,,

},,,},

,,},,

,}};數字隨便寫的,把裡面的括號全扔掉就是真實的記憶體排列了。

由於每個維度的元素數量是已知的,所以對於任意的解引用,都可以直接計算出對應的指標位置: A[1] 必然在數值為 1 的那個位置,A[1][1] 必然在數值為 2 的那個位置, A[1][2][1] 的值可知是 3 。這是乙個直觀的一層層的定位。

每次解引用,實際上只是在根據維度計算位址,並沒有做指標跳轉。

它的位址計算依賴於每個維度具體的大小,這是與普通指標的乙個重要區別,普通指標 p 如果算 p[n][m] 那就是另一種意思了。當然一維的 p[n] 還是一樣的。

另乙個重要區別是,由於多維陣列解引用得到的位址是計算出來的,是個數值,不是實際的變數,所以只能當常量使用,別想給它賦個值。

說到這裡就有個問題,既然 A 的解引用都是在它內部計算位址, A[1] 和 A[1][0] 顯然都指向數值為 1 的那個位址,那麼它們是等價的嗎?

答案是不等價

原因就是開始提到的,指標的型別是很重要的,而對 A 解引用一次和解引用兩次得到的型別完全不一樣。

A[n] 對 A 解引用一次,型別是(int [2]) [3] 的二維陣列;如果做指標的減法運算,那麼就是陣列的首位址指標(即 (int [2]) * )相減,並得到兩個指標之間的元素個數(元素型別即 int[2] ),比如 A[1] - A[0] 的結果就是數值為1的位置與首位址之間有多少個 int[2] 型別元素,結果是 3 。

A[n][m] 對 A 解引用兩次,型別是 int[2] 的陣列;如果做指標的減法運算,與上面同理,就是 int[2] 的首位址指標相減,得到其中有多少個 int 型別的元素。即使 A[1][0] 與 A[1] 是同乙個位址,但 A[1][0] - A[0][0] = 6 。

當然你可以對某個位址做強制型別轉換,得到想要的指標型別,否則它們可不能混著運算

intA[4

][3][2

];A[1

]-A[

0]==3

;A[1

][0]-

A[0][

0]==6

;(int*)A

[1]-

(int*)

A[0]

==6;//

A[1]

-A[0

][0]==

???//A[

1]:int(*

)[2],A

[0][0

]:int*

這也說明,陣列型別和指標型別不要隨便轉換,雖然用起來是完全一樣的。

最明顯的乙個例子如下,你可以對兩個陣列做完全一樣的讀寫操作,但它們完全是兩種東西,別做什麼型別轉換,最好也別做什麼加減法……

intA[3

][4];int*B

[3];for

(intm=

0;m<3;

++m)B

[m]=

A[m];

……太囉嗦,匿了。

c語言中 p a什麼意思?

Flint Stone 首先 C語言 其次這是乙個指標,指標是什麼?是控制位址的指標的常用運算子 先說後面那個,你學C語言,那麼你肯定用過scanf d n 這樣的輸入吧,n是輸入到n的位址,就是取位址符,你可以試試cout n endl 輸出是乙個位址,十六進製制的。你可以找一篇部落格好好看看。定...

C語言中 nnn是什麼意思

Tanky Woo 000 nul 001 soh 002 stx 003 etx 004 eot 005 enq 006 ack 007 bel 010 bs 011 ht 012 nl 013 vt 014 np 015 cr 016 so 017 si 020 dle 021 dc1 022 ...

在c語言中,表示式5 3的結果是什麼?

正常思路 由於邏輯運算子優先級別低於比較運算子同時這兩種都低於算術運算子,因此先考慮後半部分,4 0真值為1,而8 1的真值為0.再考慮或左邊的表示式,5 3 2顯然真值為1最終結果為1 0當然結果為12 有 將表示式分成兩部分左邊的是5 3 2顯然其真值為1因此1 任意真值都為1不用算後面的了。真...