林鹿可爱 发表于 2019-1-20 21:33:06

关于二维数组

搞不懂这道题怎么做,一点头绪都没有,感觉二维数组学得很不透彻,另外指针和二维数组的关系也不太清楚
求解析题目,求点拨一二
或者留下文档连接或者有视频资料都可以,拜托各位了

Y-Frank 发表于 2019-1-20 21:33:07

本帖最后由 Y-Frank 于 2019-1-24 22:19 编辑

二维数组表示形式                                                       含义                                                       地址
a                                                               二维数组名,指向一维数组a,即0行首地址       2000
a,*(a+0),*a                                          0行0列元素地址                                                       2000
a+1,&a                                                   1行首地址                                                                 2016
a,*(a+1)                                                    1行0列元素a的地址                                         2016
a+2,*(a+1)+2,&a                           1行2列元素a的地址                                       2024
*(a+2),*(*(a+1)+2),a                     1行2列元素a的值                                         元素值为13

指针变量的类型及含义
变量定义                                类型表示        含义
int i;                                int                定义整型变量i
int *p;                                int *                定义p为指向整型数据的指针变量
int a;                                int         定义整型数组a,它有5个元素
int *p;                                int *        定义指针数组p,它由4个指向整型数据的指针元素组成
int (*p) ;                        int (*)         p为指向包含4个元素的一维数组的指针变量
int f( );                                int ( )        f为返回整型函数值的函数
int *p( );                         int *( )        p为返回一个指针的函数,该指针指向整型数据
int (*p)( );                        int (*)( )        p为指向函数的指针,该函数返回一个整型值
int **p;                                int **        p是一个指针变量,它指向一个指向整型数据的指针变量
void *p;                                void *        p是一个指针变量,基类型为void(空类型),不指向具体的对象

ba21 发表于 2019-1-20 21:39:19

讲来讲去就是类型的区别,搞清楚什么是什么类型就行了。

数组指针和指针是两个不同的类型:
假设:int array={{1,2,3},{4,5,6}};
1,二维数组名是数组指针 (array: 是指向int (*)类型的指针)
2,二维数组名取址是二维数组指针 (&array: 是指向 int (*)类型的指针)
3,二维数第0行的首地址是数组指针(&array:是指向int (*)类型的指针)
4,二维数组首元素的地址是指针类型(array:是指向int *类型的指针)

Y-Frank 发表于 2019-1-24 22:25:34

Y-Frank 发表于 2019-1-24 22:13
二维数组表示形式                                                       含义                               ...

只是把整型换成字符型,
s是二维数组
p是指向字符型的指针变量
k是指向由包含3个元素的一维指针的指针变量
排除法也是选择c
s的含义是零行零列的首地址,因此可赋值给p

行客 发表于 2019-1-25 19:17:23

Y-Frank 发表于 2019-1-24 22:13
二维数组表示形式                                                       含义                               ...

Y-Frank回复的很不错。

Y-Frank 发表于 2019-1-25 23:18:37

行客 发表于 2019-1-25 19:17
Y-Frank回复的很不错。

{:5_109:}之前整理的点资料,看到有人问就回了下

新建word 发表于 2019-1-25 23:29:38

其实吧光说 你不大好理解 数组 以及指针的含义, 建议你把Y-Frank的代码 拷贝到 vs 编译器中 之后 下个断点看下 内存就知道了,多尝试几遍 你就能明白了~除非你抽象能力很高 。。。。

行客 发表于 2019-1-26 14:12:29

假设:int arry={{1,2,3},{4,5,6}};

咱们首先说数组名,后面不带下标的。我们有规律的从&arry、arry、*arry分别代表什么说起:

1、&arry是arry的地址,它代表整个二维数组的地址:
  int (*p)=&arry;

2、二维数组名arry是数组第一行的地址,它代表的是一整行:
  int (*p)=arry;

3、*arry才是arry的地址,是一个元素的地址,它代表的是一个具体元素:
  int *p=*arry;

然后我们说带下标的,我们继续有规律的从arry、arry、arry分别代表什么说起:

1、arry就是代表了第一个元素,即1:
所以上面的
int *p=*arry;
也可以替换为
int *p=&arry;

2、arry代表了第一行,即{1,2,3}:
printf("%d\n",sizeof(arry));
可以看到输出为12。
同样上面的
int (*p)=arry;
也可以替换为
int (*p)=&arry;

3、arry当然代表了数组第一行的地址,见上。&arry代表了整个二维数组的地址。

还有什么情况没讲到?似乎都讲到了。。。

Y-Frank 发表于 2019-1-27 00:08:16

本帖最后由 Y-Frank 于 2019-1-27 00:15 编辑

接着你的东西来说下吧,
行客 讲的重点在于:
1.数组名不代表整个数组,只代表数组首元素的地址:
        如果arry是一维数组,那么它代表arry的地址,即为首元素的地址
        若arry是二维数组,二维数组可看成数组的数组(一个数组里面每个元素都是长度相同的数组),那么它代表的就是arry的地址,首行元素的地址
2. &和*两个符号
        &是取地址运算符,&a是变量a的地址,那么二维数组arry中的&arry代表的就是arry整个二维数组的首地址
        *是* 指针运算符(或“间接访问”运算符),表示指向,*p代表指针变量p指向的对象,那么二维数组arry中的*arry代表的即为arry的值,arry是一个一维数组名,因此它代表的是arry的地址

3.[]实际上是变址运算符,即将a按a+i计算地址,然后找出该地址单元中的值。

有风陪伴的日子 发表于 2019-1-27 23:19:09

Y-Frank 发表于 2019-1-24 22:13
二维数组表示形式                                                       含义                               ...

A选项不对吗?

Y-Frank 发表于 2019-1-28 00:49:32

有风陪伴的日子 发表于 2019-1-27 23:19
A选项不对吗?

不对,
需要改成
p=&s
//因为p是一个指向字符类型的指针,因此它的值应该是一个字符元素的地址
//a选项是p=s,s代表的是0行的首地址,虽然值一样,
//但是它的类型是char   ,是一个数组,不能把字符数组的地址赋给一个字符指针对象
//若要执行p=s,则p的定义应该为char (*p)
或者
C选项p=s,s是一个数组名,它代表的是其首元素的地址,即为s的地址
//等同于上面解释的p=&s
或者
p=*s
//s数组名代表的是元素s的地址,加上*指针运算符,就相当于向内拨开一层,即代表的是s的地址

这题的关键在于类型要相同才能赋值,即右侧的值的类型与左侧变量的类型应当一致
k是char(*),即指向包含3个字符元素的一维数组的指针变量
p是char *,即指向字符型数据的指针变量
s值是类型为char 的地址,即一维数组s的首地址
//类型决定了通过指针变量来操作指向的数据,是从起始地址开始的顺序几个字节中存取数据,
//如果是int型,那就是从地址开始的2个字节中存取数据,
//如果是float型,那就是从地址开始的4个字节中存取数据。
s值是类型为char字符的地址,即s的地址,因此赋值没有问题

再说说b和d吧
b选项:
k是一个指针变量,b选项是把k的值(地址)赋值给p
虽然可以强制转换,但是两指针类型不同因此赋值会有问题
还有一个问题就是,指针变量未被初始化,指针变量就不会被分配存储空间。在程序中如果使用了未被分配 空间的指针,就会出现难以查找的错误。

d选项:
虽然k是指向一维数组的指针,且s的值也是一维数组的首地址
但是两者的长度不同,k是指向含有3个字符的数组,char (*)
s的值却是char 的地址

有风陪伴的日子 发表于 2019-1-29 21:21:04

Y-Frank 发表于 2019-1-28 00:49
不对,
需要改成
p=&s


   哦,我明白了,是因为指向的级别不同。
   s是一个二维数组,而*p是一级指针,直接指向s就是越级,所以p不能直接通过s指向s,只能指向s.若想要指向s,则需要一个二级指针**q,令p=s,q=&p就可以了,或者也可以直接p=&s,反正就是不能直接通过指向上一级数组就指向下一级。
   由于数组的第一个元素比较特别,s,s,s都是相等的,所以会有一定的迷惑性,如p=s,由于s是一个二维数组,所以p并没有指向具体的元素s,而是指向了一个一维数组s,但它们的地址是相等的,所以这并没有影响到p的值。如果举一个一般情况,如s,想要指向这个元素,就得p=*(s+0)+3,而指向s,其实就是p=*(s+0)+0,都是经过一定的变化才能得到,只不过+0就相当于没加一样。

顺带一提,我之前一直用vc++6.0写C语言,这里,写成p=s不但不会出错,还可以正确地得到s的地址,但会有一处警告:
                           'char *' differs in levels of indirection from 'char (*)'
                              ‘char*‘与‘char(*)’的间接级别不同

最近一直在学Python,c语言有些忘了,经过这一次,总算想起来了,感谢你这么耐心的回答我的问题
{:5_91:}{:5_91:}

Y-Frank 发表于 2019-1-30 00:09:56

有风陪伴的日子 发表于 2019-1-29 21:21
哦,我明白了,是因为指向的级别不同。
   s是一个二维数组,而*p是一级指针,直接指向s[ ...

嘻嘻不客气啦,最近我也在学习python哈哈
页: [1]
查看完整版本: 关于二维数组