再次看這篇文章,感覺說的好多都是廢話,在文章最前面補(bǔ)充一句話:
“[]的優(yōu)先級(jí)高于*
”,大家可以帶著這句話看下面的~~~
========================
再一次的見證了自己的基礎(chǔ)不牢靠。。。幸好發(fā)現(xiàn)得早,看見網(wǎng)上說,華為的一個(gè)面試題就考了這個(gè)方面的。
借那道華為的面試題引出問題,題目:
char **p, a[16][8]; 問:p=a是否會(huì)導(dǎo)致程序在以后出現(xiàn)問題?為什么?
可能有一部分朋友會(huì)回答正確,這里他們認(rèn)為,a[]是一級(jí)指針,a[][]就是二級(jí)指針。那這個(gè)到底對(duì)不對(duì)呢?
OK,用事實(shí)說話:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// Author: Tanky Woo
// Blog: www.WuTianQi.com
// Note: 驗(yàn)證二維數(shù)組與二級(jí)指針的傳遞問題
#include <iostream>
using namespace std;
void Test(char **p)
{
cout << p[0][0] << endl;
}
int main()
{
char a[2][3];
Test(a);
return 0;
}
|
結(jié)果報(bào)錯(cuò):
1
2
|
// error C2664: “Test”: 不能將參數(shù) 1 從“char [2][3]”轉(zhuǎn)換為“char **”
// 與指向的類型無關(guān);轉(zhuǎn)換要求 reinterpret_cast、C 樣式轉(zhuǎn)換或函數(shù)樣式轉(zhuǎn)換
|
于是乎,我看了下《C專家編程》里10.5節(jié)—使用指針向函數(shù)傳遞一個(gè)多維數(shù)組:
方法一:
函數(shù)是:
1
|
void fun1(int arr[2][3]);
|
這種方法導(dǎo)致只能處理2行3列的int型數(shù)組。
方法二:
可以省略第一維的長(zhǎng)度。
函數(shù)是:
1
|
void fun2(int arr[][3]);
|
這種方法的限制略微寬松了一些,但是還是只能處理每行是3個(gè)整數(shù)長(zhǎng)度的數(shù)組。
函數(shù)也可以寫成:
1
|
void fun2_2(int (*arrr)[3]);
|
方法三:
創(chuàng)建一個(gè)一維數(shù)組,數(shù)組中的元素是指向其他東西的指針。也可以說是二級(jí)指針。
函數(shù)是:
注意:只有把二維數(shù)組改為一個(gè)指向向量的指針數(shù)組的前提下才可以這么做!
比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <iostream>
using namespace std;
void test(char **ptr)
{
cout << *ptr << endl;
}
int main()
{
char *p[3] = {"abc", "def", "ghi"};
test(p);
return 0;
}
|
在《C專家編程》10.3節(jié)的小啟發(fā)里講的很透徹:(以下這段文字及對(duì)比一定要認(rèn)真分析!)
數(shù)組和指針參數(shù)是如何被編譯器修改的?
“數(shù)組名被改寫成一個(gè)指針參數(shù)”規(guī)則并不是遞歸定義的。數(shù)組的數(shù)組會(huì)被改寫成“數(shù)組的指針”,而不是“指針的指針”:
實(shí)參 所匹配的形參
數(shù)組的數(shù)組 char c[8][10]; char (*)[10]; 數(shù)組指針
指針數(shù)組 char *c[10]; char **c; 指針的指針
數(shù)組指針(行指針) char (*c)[10]; char (*c)[10]; 不改變
指針的指針 char **c; char **c; 不改變
我在CSDN上專門為這個(gè)問題提問過:
http://topic.csdn.net/u/20101221/12/da817bda-4e88-44df-bdf8-40e8f44aacb8.html?2076366575
最后我總結(jié)下討論結(jié)果:
只要實(shí)參的類型與形參的類型一致(或可轉(zhuǎn)換)就行。
為什么這么說呢?
piaojun_pj朋友給了一段代碼,分析得很給力:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// VectorTest.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int arr1[3];
int arr2[3];
int arr3[3];
int * ptr;
// ptr1是一個(gè)指向 int [3] 的指針,即ptr的類型和&arr1的類型是一樣的,注意:arr1指向的內(nèi)存區(qū)域定長(zhǎng)
int ptr1[3][3]={{1,2,3},{1,2,3},{1,2,3}};
// ptr2是一個(gè)指向 int * 的指針,即ptr2的類型和&ptr是一樣的,注意:ptr指向的內(nèi)存區(qū)域不定長(zhǎng)
int * ptr2[3]={arr1,arr2,arr3};
// ptr3是一個(gè)指向 int [3] 的指針,即ptr3的類型和&arr1的類型是一樣的,注意:arr1指向的內(nèi)存區(qū)域定長(zhǎng)
int(* ptr3)[3]=&arr1;
ptr3=ptr1; // 沒錯(cuò),他們的類型相同
// ptr3=ptr2;//error 無法從“int *[3]”轉(zhuǎn)換為“int (*)[3]
// ptr4是一個(gè)指向 int * 的指針,即ptr4的類型和&ptr是一樣的,注意:ptr指向的內(nèi)存區(qū)域不定長(zhǎng)
int ** ptr4;
//ptr4=&arr1; //error 無法從“int (*)[3]”轉(zhuǎn)換為“int **
ptr4=ptr2; // 沒錯(cuò),他們的類型相同
//ptr4=ptr3; // error 無法從“int (*)[3]”轉(zhuǎn)換為“int **
return 0;
}
|
From: http://www.wutianqi.com/?p=1822