博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二维数组和二级指针
阅读量:4109 次
发布时间:2019-05-25

本文共 5301 字,大约阅读时间需要 17 分钟。

    入职一年了,这一年自己学到许多,但是忘记也很多,于是决定定下心来整理以前学到的,并且继续学习
    
    二维数组和二级指针,这真是头疼的问题,困扰了我好几次,
   
    先转一下的二维数组和二级指针

前两天写个程序,传参数的时候想传个二维数组进去,结果悲剧了,函数写成Fun (int **p){},原来没有这么写过,

以为这么写也是对的,结果错了,查了些资料,做个总结。

Fun (int **p){}这里面的int **p //这里的p不是二维数组的指针,而是指向指针的指针,即二级指针。

正确的二维数组的指针应该是:Int a[2][2];Int (*p)[2];//定义时无论数组维数,只可忽略第一维

例如:int a[2][2]={0,1,2,3};

int **p=(int**)a;//强制将二维数组指针转为指向指针的指针

则此时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);

对于p[0][0]:由于*p=0; ====> **p=*(0);引用地址为零的内存,必然是错误的。

对于p[0][1]=*(*p+1)====>*(4),引用了非法内存同样,

对于p[1][0]=*(1),p[1][1]=*(5),均引用了非法内存所以说,二位数组并不能简单的转换成指向指针的指针。

二维数组其实只是一个指针,而二级指针是指向指针的指针,所以二者并不等价。如上例所示:int a[2][2];

a是指向整个数组的首地址,并不是int **;所以不要指望向函数fun里面传实参 p=a;

 

感謝,我覺得那個應該是和下面的情況類似把,中間有個強制轉換的過程:

 

#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程序设计语言>中的关于这个的解释:

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" };

//我的理解是,当是指针数组的时候,可以直接传,如果是普通的二维数组的话应该就进行上面的转换。

    一下是自己遇到问题:

    问题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

最终通过上面蓝色部分找到了到了答案,简单的说就是

二维数组其实只是一个指针,而

二级指针是指向指针的指针,所以二者并不等价。

 

但是可以强转

如:

1
 
int
 iaArray[
2
][
2
=
 
{
1124}
;
2
 
3
 
int
 
**
=
 (
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;
这样就是正确的。
问题2:
下面的问题:很有意思
1
#include
<
iostream
>
2
using
namespace
std;
3
4
int
main()
5
{
6int iaArray[5]= {
1,2, 3,4, 5}
;
7
8#if 0
9
10int *p = (int*)(&iaArray+1)-1;
11 cout<<*p<<endl;
12
13int *q = (int*)(&iaArray+1);
14 cout<<*(q-1)<<endl;
15
16int **qq = (int**)(&iaArray+1);
17 cout<<*(qq-1)<<endl;
18
19#else
20int iaAry[2][2]= {
1,2, 3,4}
;
21
22int *p = (int*)(&iaAry+1)-1;
23 cout<<*p<<endl;
24
25int *q = (int*)(&iaAry+1);
26 cout<<*(q-1)<<endl;
27
28int **qq = (int**)(&iaAry+1);
29 cout<<*(qq-1)<<endl;
30#endif
31return 0;
32}
上面的结果都是5,下面的结果都是4
主要说明的是:
不管是二维数组,还是一维数组
数组的首地址取地址+1,增加整个数组的长度;
如上面的例子:
    3:注意函数传递,指针,引用
    在指针引用&*,**的时候是改变的指针,这个一般主要是里面涉及到内存分配,
    或者获取的是静态区域,或者是全局的区域,传递的时候一般都是传,空指针。
     传递*,&,是改变的数组的值。一般都是传递的是非空的,一般要再函数中增加
      assert(NULL != p);
    
     4.const ,Enum,static const ...待续

转载地址:http://vqosi.baihongyu.com/

你可能感兴趣的文章
过滤器及JSP九大隐式对象
查看>>
软件(项目)的分层
查看>>
菜单树
查看>>
MySQL-分布式架构-MyCAT
查看>>
设计模式六大原则(6):开闭原则
查看>>
阿里面试总结--JAVA
查看>>
Servlet的生命周期
查看>>
JAVA八大经典书籍,你看过几本?
查看>>
《读书笔记》—–书单推荐
查看>>
【设计模式】—-(2)工厂方法模式(创建型)
查看>>
有return的情况下try catch finally的执行顺序(最有说服力的总结)
查看>>
String s1 = new String("abc"); String s2 = ("abc");
查看>>
JAVA数据类型
查看>>
Xshell 4 入门
查看>>
SoapUI-入门
查看>>
Oracle -常用命令
查看>>
JAVA技术简称
查看>>
ORACLE模糊查询优化浅谈
查看>>
2016——个人年度总结
查看>>
2017——新的开始,加油!
查看>>