关于二维数组
搞不懂这道题怎么做,一点头绪都没有,感觉二维数组学得很不透彻,另外指针和二维数组的关系也不太清楚求解析题目,求点拨一二
或者留下文档连接或者有视频资料都可以,拜托各位了 本帖最后由 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(空类型),不指向具体的对象
讲来讲去就是类型的区别,搞清楚什么是什么类型就行了。
数组指针和指针是两个不同的类型:
假设: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:13
二维数组表示形式 含义 ...
只是把整型换成字符型,
s是二维数组
p是指向字符型的指针变量
k是指向由包含3个元素的一维指针的指针变量
排除法也是选择c
s的含义是零行零列的首地址,因此可赋值给p
Y-Frank 发表于 2019-1-24 22:13
二维数组表示形式 含义 ...
Y-Frank回复的很不错。 行客 发表于 2019-1-25 19:17
Y-Frank回复的很不错。
{:5_109:}之前整理的点资料,看到有人问就回了下 其实吧光说 你不大好理解 数组 以及指针的含义, 建议你把Y-Frank的代码 拷贝到 vs 编译器中 之后 下个断点看下 内存就知道了,多尝试几遍 你就能明白了~除非你抽象能力很高 。。。。 假设: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:15 编辑
接着你的东西来说下吧,
行客 讲的重点在于:
1.数组名不代表整个数组,只代表数组首元素的地址:
如果arry是一维数组,那么它代表arry的地址,即为首元素的地址
若arry是二维数组,二维数组可看成数组的数组(一个数组里面每个元素都是长度相同的数组),那么它代表的就是arry的地址,首行元素的地址
2. &和*两个符号
&是取地址运算符,&a是变量a的地址,那么二维数组arry中的&arry代表的就是arry整个二维数组的首地址
*是* 指针运算符(或“间接访问”运算符),表示指向,*p代表指针变量p指向的对象,那么二维数组arry中的*arry代表的即为arry的值,arry是一个一维数组名,因此它代表的是arry的地址
3.[]实际上是变址运算符,即将a按a+i计算地址,然后找出该地址单元中的值。 Y-Frank 发表于 2019-1-24 22:13
二维数组表示形式 含义 ...
A选项不对吗? 有风陪伴的日子 发表于 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 的地址 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:} 有风陪伴的日子 发表于 2019-1-29 21:21
哦,我明白了,是因为指向的级别不同。
s是一个二维数组,而*p是一级指针,直接指向s[ ...
嘻嘻不客气啦,最近我也在学习python哈哈
页:
[1]