入職一年了,這一年自己學(xué)到許多,但是忘記也很多,于是決定定下心來(lái)整理以前學(xué)到的,并且繼續(xù)學(xué)習(xí)
二維數(shù)組和二級(jí)指針,這真是頭疼的問(wèn)題,困擾了我好幾次,
先轉(zhuǎn)一下
wanpengcoder的二維數(shù)組和二級(jí)指針
前兩天寫個(gè)程序,傳參數(shù)的時(shí)候想傳個(gè)二維數(shù)組進(jìn)去,結(jié)果悲劇了,函數(shù)寫成Fun (int **p){},原來(lái)沒(méi)有這么寫過(guò),
以為這么寫也是對(duì)的,結(jié)果錯(cuò)了,查了些資料,做個(gè)總結(jié)。
Fun (int **p){}這里面的int **p //這里的p不是二維數(shù)組的指針,而是指向指針的指針,即二級(jí)指針。
正確的二維數(shù)組的指針應(yīng)該是:Int a[2][2];Int (*p)[2];//定義時(shí)無(wú)論數(shù)組維數(shù),只可忽略第一維
例如:int a[2][2]={0,1,2,3};
int **p=(int**)a;//強(qiáng)制將二維數(shù)組指針轉(zhuǎn)為指向指針的指針
則此時(shí)p[0]=0;p[1]=1;p[2]=2;p[3]=3;
而p[0][0]=*(*(p+0)+0)=**p;
p[0][1]=*(*(p+0)+1);
對(duì)于p[0][0]:由于*p=0; ====> **p=*(0);引用地址為零的內(nèi)存,必然是錯(cuò)誤的。
對(duì)于p[0][1]=*(*p+1)====>*(4),引用了非法內(nèi)存同樣,
對(duì)于p[1][0]=*(1),p[1][1]=*(5),均引用了非法內(nèi)存所以說(shuō),二位數(shù)組并不能簡(jiǎn)單的轉(zhuǎn)換成指向指針的指針。
二維數(shù)組其實(shí)只是一個(gè)指針,而二級(jí)指針是指向指針的指針,所以二者并不等價(jià)。如上例所示:int a[2][2];
a是指向整個(gè)數(shù)組的首地址,并不是int **;所以不要指望向函數(shù)fun里面?zhèn)鲗?shí)參 p=a;
感謝,我覺(jué)得那個(gè)應(yīng)該是和下面的情況類似把,中間有個(gè)強(qiáng)制轉(zhuǎn)換的過(guò)程:
#include <iostream>
void fun(char ** p)
{
char (*p1)[10] = (char(*)[10])p;
std::cout<<p1[0][0]<<std::endl;
}
int main(int argc, char* argv[])
{
char data[][10] = {"abc","def"};
fun((char **)data);
return 0;
}
----------------------------------------------------------------華麗的分割線---------------------------------------------------------------------------------------------------------------------------
<c程序設(shè)計(jì)語(yǔ)言>中的關(guān)于這個(gè)的解釋:
Newcomers to C are sometimes confused about the difference between a two-dimensional array and an array of pointers, such as name in the example above. Given the definitions
int a[10][20];
int *b[10];
then a[3][4] and b[3][4] are both syntactically legal references to a single int. But a is a true two-dimensional array: 200 int-sized locations have been set aside, and the conventional rectangular subscript calculation 20 * row +col is used to find the element a[row,col]. For b, however, the definition only allocates 10 pointers and does not initialize them; initialization must be done explicitly, either statically or with code. Assuming that each element of b does point to a twenty-element array, then there will be 200 ints set aside, plus ten cells for the pointers. The important advantage of the pointer array is that the rows of the array may be of different lengths. That is, each element of b need not point to a twenty-element vector; some may point to two elements, some to fifty, and some to none at all.
Although we have phrased this discussion in terms of integers, by far the most frequent use of arrays of pointers is to store character strings of diverse lengths, as in the function month_name. Compare the declaration and picture for an array of pointers:
char *name[] = { "Illegal month", "Jan", "Feb", "Mar" };?

with those for a two-dimensional array:
char aname[][15] = { "Illegal month", "Jan", "Feb", "Mar" };

//我的理解是,當(dāng)是指針數(shù)組的時(shí)候,可以直接傳,如果是普通的二維數(shù)組的話應(yīng)該就進(jìn)行上面的轉(zhuǎn)換。
一下是自己遇到問(wèn)題:
問(wèn)題1:
1
#include "stdafx.h"
2
3
#include <iostream>
4
using namespace std;
5
6
7
typedef struct tagNode_st
8

{
9
char m_acData[10];
10
int m_iNo;
11
}Node_st;
12
13
Node_st Root;
14
15
int Fun(Node_st ** pst)
16

{
17
//Error
18
#if 0
19
Node_st astNodeA[2] =
{
{"xiaowang", 1},
{"xiaoming", 2}};
20
#else
21
static Node_st astNodeA[2] =
{
{"xiaowang1", 1},
{"xiaoming1", 1}};
22
#endif
23
//static Node_st astNodeB[2] = {{"xiaowang2", 2}, {"xiaoming2", 2}};
24
//static Node_st astNodeC[2] = {{"xiaowang3", 3}, {"xiaoming3", 3}};
25
*pst = astNodeA;
26
27
return 0;
28
}
29
30
int _tmain(int argc, _TCHAR* argv[])
31

{
32
Node_st st[2][2];
33
34
//TypeA
35
Fun((Node_st**)st);
36
//1.error
37
cout<<st[0][0].m_acData<<endl;
38
cout<<st[0][0].m_iNo<<endl<<endl;
39
40
//2.error
41
cout<<(*st)->m_acData<<endl;
42
cout<<(*st)->m_iNo<<endl<<endl;
43
44
//3.right
45
cout<<(*(Node_st**)st)->m_acData<<endl;
46
cout<<(*(Node_st**)st)->m_iNo<<endl<<endl;
47
48
//Typde B
49
Node_st *pstTemp[2] =
{&st[0][0], &st[1][0]};
50
Fun(&pstTemp[0]);
51
//Right
52
cout<<(pstTemp[0])->m_acData<<endl;
53
cout<<(pstTemp[0])->m_iNo<<endl<<endl;
54
55
//Error
56
cout<<(st[0][0]).m_acData<<endl;
57
cout<<(st[0][0]).m_iNo<<endl<<endl;
58
59
//Right
60
cout<<(*(Node_st**)st)->m_acData<<endl;
61
cout<<(*(Node_st**)st)->m_iNo<<endl<<endl;
62
63
//Typde C
64
65
Node_st *pstTemp2[2] =
{NULL, NULL};
66
Fun(&pstTemp2[0]);
67
//Right
68
cout<<(pstTemp2[0])->m_acData<<endl;
69
cout<<(pstTemp2[0])->m_iNo<<endl<<endl;
70
71
return 0;
72
}
73
最終通過(guò)上面藍(lán)色部分找到了到了答案,簡(jiǎn)單的說(shuō)就是
二維數(shù)組其實(shí)只是一個(gè)指針,而
二級(jí)指針是指向指針的指針,所以二者并不等價(jià)。
但是可以強(qiáng)轉(zhuǎn)
如:
1
int iaArray[2][2] =
{1, 1, 2, 4};
2
3
int **q = (int**)iaArray;
4
5
for (int i = 0; i < 4; ++ i)
6
{
7
cout<<"i:"<<i<<" "<<q[i]<<endl;
8
}
9
和:
1
int iaArrayTemp[5] =
{1, 2, 3, 4, 5};
2
int **p = (int**)&iaArrayTemp;
3
p++;
4
cout<<*p<<endl; 這樣就是正確的。
問(wèn)題2:
下面的問(wèn)題:很有意思
1
#include <iostream>
2
using namespace std;
3
4
int main()
5

{
6
int iaArray[5] =
{1, 2, 3, 4, 5};
7
8
#if 0
9
10
int *p = (int*)(&iaArray+1)-1;
11
cout<<*p<<endl;
12
13
int *q = (int*)(&iaArray+1);
14
cout<<*(q-1)<<endl;
15
16
int **qq = (int**)(&iaArray+1);
17
cout<<*(qq-1)<<endl;
18
19
#else
20
int iaAry[2][2] =
{1, 2, 3, 4};
21
22
int *p = (int*)(&iaAry+1)-1;
23
cout<<*p<<endl;
24
25
int *q = (int*)(&iaAry+1);
26
cout<<*(q-1)<<endl;
27
28
int **qq = (int**)(&iaAry+1);
29
cout<<*(qq-1)<<endl;
30
#endif
31
return 0;
32
} 上面的結(jié)果都是5,下面的結(jié)果都是4
主要說(shuō)明的是:
不管是二維數(shù)組,還是一維數(shù)組
數(shù)組的首地址取地址+1,增加整個(gè)數(shù)組的長(zhǎng)度;
如上面的例子:
3:注意函數(shù)傳遞,指針,引用
在指針引用&*,**的時(shí)候是改變的指針,這個(gè)一般主要是里面涉及到內(nèi)存分配,
或者獲取的是靜態(tài)區(qū)域,或者是全局的區(qū)域,傳遞的時(shí)候一般都是傳,空指針。
傳遞*,&,是改變的數(shù)組的值。一般都是傳遞的是非空的,一般要再函數(shù)中增加
assert(NULL != p);
4.const ,Enum,static const ...待續(xù)
快0:00,笑一笑,睡覺(jué)了