各位大神帮我听听秋的声音ppt课件,这声音正常吗

C_C++_二维数组与二维指针的地址与访问关系
#include &stdio.h&
#include &stdlib.h&
#include &string.h&
#define ROW 3
#define COL 5
int main()
int *a;  //一维线性存储
   
int **b; //二维存储
int arr[ROW][COL] = {0};
printf(&sizeof(int) = %d\n&,sizeof(int));
printf(&\n数组地址:\n&);
for(i=0; i&ROW; i++)
for(j=0; j&COL; j++)
arr[i][j] = i+j;
// printf(&%p &,*(arr+i)+j); //访问方式一
printf(&%p &,&arr[i][j]); //访问方式二
printf(&-&%d &,arr[i][j]);
//printf(&%p
&,(int *)arr+i*COL+j); //OK
//printf(&%d \n&,*((int *)arr+i*COL+j)); //OK
printf(&\n&);
VC6.0运行结果:
数组地址:
0012FF04 -&0 0012FF08 -&1 0012FF0C -&2 0012FF10 -&3 0012FF14 -&4
0012FF18 -&1 0012FF1C -&2 0012FF20 -&3 0012FF24 -&4 0012FF28 -&5
0012FF2C -&2 0012FF30 -&3 0012FF34 -&4 0012FF38 -&5 0012FF3C -&6
证明了对于数组可以用数组形式访问,也可用指针形式访问,
即可以把数组名当指针来用,且数组单元地址连续
可以用:arr[i][j] 和 *(*(arr+i)+j) 和 *((int *)arr+i*COL+j)
printf(&\n&);
//一次性分配足够内存地址是连续的
a = (int *)malloc(sizeof(int)*ROW*COL);
memcpy(a,arr,sizeof(int)*ROW*COL);
printf(&二维指针一次性动态分配足够内存的地址:\n&);
for(i=0; i&ROW; i++)
for(j=0; j&COL; j++)
//printf(&%d &,a[i][j]); //error
//printf(&%p &,*(*(a+i)+j)); //error
printf(&%p &,a+i*COL+j);
printf(&-&%d &,*(a+i*COL+j));
printf(&\n&);
VC6.0运行结果:
二维指针一次性动态分配足够内存的地址:
00580F08 -&0 00580F0C -&1 00580F10 -&2 00580F14 -&3 00580F18 -&4
00580F1C -&1 00580F20 -&2 00580F24 -&3 00580F28 -&4 00580F2C -&5
00580F30 -&2 00580F34 -&3 00580F38 -&4 00580F3C -&5 00580F40 -&6
证明了对于一次性分配的二维指针指向的内存来说,内存单元地址连续且呈线性分布,
但该指针不能做数组名使用,以数组名访问会出错,访问时要注意元素间隔。
可以用:*((int *)a+i*COL+j)
不能用:a[i][j] 和 *(*(a+i)+j)
printf(&\n&);
printf(&二维指针两次分配内存:\n&);
b = (int **)malloc(sizeof(int *)*ROW);
for(i=0; i&ROW; i++)
b[i] = (int *)malloc(sizeof(int)*COL);
for(i=0; i&ROW; i++)
for(j=0; j&COL; j++)
b[i][j] = arr[i][j];
//printf(&%p &,&b[i][j]); //访问方式一 ok
printf(&%p &,*(b+i)+j); //访问方式二 ok
printf(&-&%d &,*(*(b+i)+j));
//printf(&%p \n&,*((int *)b+i*ROW+j));//error
printf(&\n&);
VC6.0运行结果:
二维指针两次分配内存:
003D0FA8 -&0 003D0FAC -&1 003D0FB0 -&2 003D0FB4 -&3 003D0FB8 -&4
003D0FF0 -&1 003D0FF4 -&2 003D0FF8 -&3 003D0FFC -&4 003D1000 -&5
003D1038 -&2 003D103C -&3 003D1040 -&4 003D1044 -&5 003D1048 -&6
证明了对二维指针两次分配内存,对每一次malloc操作分配的内存是连续的,
但这一次malloc操作与下一次malloc操作分配的内存地址不是相连的,
特殊情况下会相连,这种情况比较少。
访问的时候可以作指针形式访问,也可以做数组形式访问
可以用:b[i][j] 和 *(*(b+i)+j);
但是不能用:*((int *)b+i*ROW+j)
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?您所在的位置: &
理解二维数组的地址
理解二维数组的地址
电子工业出版社
《C语言开发手册(典藏版)》第9章指针,本章首先介绍了C语言中指针的使用,主要包括指针的概念、指针变量的声明和赋值,接着详细讲解了指针和数组的关系及指针的运算规则,然后介绍了指向多维数组的指针。同时,本章还对几种特殊的指针进行了详细的介绍,主要包括字符串指针、指针数组、指向指针的指针、指针和函数等。最后,本章还总结了指针的学习要点。本节为大家介绍二维数组的地址。
9.5& 指向多维数组的指针
前面介绍了用指针变量指向一维数组,然后用指针操作数组元素的情况。当然,也可使用指针指向多维数组,只是使用指针处理多维数组时的概念要复杂很多。下面以操作二维数组为例进行介绍。
9.5.1& 理解二维数组的地址
假设定义一个4行5列的二维数组,示例如下:int&a[4][5];&
由于数组名代表数组的起始地址,所以a和第一个元素a[0][0]地址的数字是相同的,但是意义却不同。
二维数组在逻辑上是由行和列组成的,因此,对二维数组可以将其分为三层来理解,如图9-23所示。
第一层将数组a看做为一个变量;
第二层将二维数组a看做为一个一维数组,由a[0]、a[1]、a[2]、a[3]等4个元素组成;
第三层将第二层中的每个数组元素看做为一个单独的数组。
(点击查看大图)图9-23& 二维数组
下面编写程序分别查看每一层的地址情况。
首先,在第一层中将数组a作为一个变量,该变量的地址为&a,变量长度为sizeof(a)。使用以下程序可得到变量a的地址,以及变量a的长度。
【程序9-9】#include&&&//头文件 &#include&&&int&main() &{ &&&&&int&a[4][5];&&&&&&&&//声明变量 &&&&&&printf("变量a的地址:%d\n",&a);&&&//输出 &&&&&printf("变量a的长度:%d\n",sizeof(a)); &&&&&&system("pause"); &&&&&return&0; &}&
在该程序中,将数组看做为一个单独的变量。然后,使用取地址运算&得到变量a的地址,使用sizeof运算符得到变量a占用的内存单元数量。
编译执行这段程序,得到如下结果,如图9-24所示。从结果看出,使用&运算符也可取得数组名的地址。数组a的长度为元素数量乘以每个元素占用的字节,4行5列共20个元素,每个元素占用4个字节,所以变量a占用80个字节。
在第二层中,将数组a看做为一维数组,它有4个元素a[0]、a[1]、a[2]、a[3]。数组的首地址为a或&a[0](第一个元素的地址也是首地址)。使用sizeof(a[0])可得到数组元素的长度。
【程序9-10】#include&&&//头文件 &#include&&&int&main() &{ &&&&&int&a[4][5],i;&&&&&&//声明变量 &&&&&&printf("数组a的首地址:%d\n",a); &&&&&for(i=0;i;i++)&&&&//循环输出数组元素地址 &&&&&{ &&&&&&&&&printf("数组a第%d个元素的地址:%d\n",i+1,&a[i]); &&&&&} &&&&&printf("数组元素a[0]的长度:%d\n",sizeof(a[0])); &&&&&&system("pause"); &&&&&return&0; &}&
编译执行这段程序,得到如下结果,如图9-25所示。在其他计算机中运行该程序,得到的地址值可能不同,但每个元素的地址之间的差值肯定是相同的。
图9-24& 执行结果
图9-25& 执行结果
以上程序将数组a看做一个一维数组,由4个元素组成。首先输出数组首地址(这里没有使用取地址运算符,因为数组名就是一个指针常量,因此也可得到数组首地址)。然后,循环输出4个数组元素的地址,从执行结果可看出,数组首地址和第一个元素的地址相同,而每个数组元素的地址相差为20,表示每个数组元素的长度为20。最后,程序使用sizeof(a[0])得到数组元素a[0]的长度果真为20。
从以上结果可看出,将二维数组a作为一维数组看待时,其每个元素的长度就是二维数组中一行元素的长度之和。
在第三层中,第二层中的每一个元素又由5个元素构成。如a[0]又由a[0][0]、a[0][1]、a[0][2]、a[0][3]、a[0][4]等5个元素组成。当将a[0]作为一个数组名称时,该数组的首地址也就保存在a[0]中(这里a[0]作为一个整体,看做数组名,不是一个数组的元素),不用取地址运算符&,直接输出a[0]的值就可得到数组的首地址。
【程序9-11】#include&&&//头文件 &#include&&&int&main() &{ &&&&&int&a[4][5],i;&&&&&&//声明变量 &&&&&&printf("数组a的首地址:%d\n",a); &&&&&for(i=0;i;i++) &&&&&{ &&&&&&&&&printf("数组a[%d]的首地址:%d\n",i,a[i]);//输出首地址 &&&&&} &&&&&&for(i=0;i;i++)&&&&//输出每个元素的地址 &&&&&{ &&&&&&&&&printf("数组a[0]的第%d个元素的地址:%d\n",i+1,&a[0][i]); &&&&&} &&&&&printf("数组a[0]中的元素a[0][0]的长度:%d\n",sizeof(a[0][0])); &&&&&&system("pause"); &&&&&return&0; &}&
编译执行这段程序,得到如下结果,如图9-26所示。
图9-26& 执行结果以上程序将数组第二层中的每个元素作为一个数组名,通过程序循环输出4个数组的首地址(对比一下,与该程序中一维数组每个数组元素的地址相同)。将a[0]、a[1]、a[2]、a[3]分别看做4个单独的数组,输出数组a[0]中5个元素的地址。从输出结果可看出每个元素相差4个字节,即每个元素占用4个字节,从程序输出的结果中验证了这一点。
【责任编辑: TEL:(010)】&&&&&&
关于&&&&的更多文章
这本书是写给程序员和项目经理的。作者结合自身的丰富成长历程,
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
多年来,Imar Spaanjaars一直是ASP.NET相关图书的畅销
《C#高级编程(第8版)》是C# 2012和.NET 4.5高级技术的
《Android 4 游戏入门经典(第3版)》将赋予您惊人的灵
本书是作者深入研究SQL Server 2005数据库体系结构和内部机制的经验总结。
全书不拘泥于具体的管理操作,而是通过对存储的数据
51CTO旗下网站新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
白手起家, 积分 2, 距离下一级还需 198 积分
论坛徽章:0
我现在编写一个程序,想在子函数中,用二维数组做形参,得到一个不同维数的二维数组,怎么把这个新得到的二维数组地址,传到被调用处啊?
子函数怎么写啊?是不是得用指向一维数组的指针来做啊?大家给举一个小例子?
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
稍有积蓄, 积分 283, 距离下一级还需 217 积分
论坛徽章:1
你这是自找麻烦,不管多少维的数组,都是指针,你可以直接传递指针就可以了。解析的时候当成一维或二维就可以了。数组名和指针的区别(数组名不是指针,是数组首地址)_Linux编程_Linux公社-Linux系统门户网站
你好,游客
数组名和指针的区别(数组名不是指针,是数组首地址)
来源:Linux社区&
作者:zhangzihan
听了一堂C语言的课,那老师说:&数组名就是一个指向数组首地址的常量指针&。我上百度查了一些,有好多教程、书籍等,都持相同的观点。但我一直感觉&&数组名不等于指针。
实践是检验真理的唯一标准,于此,有了以下内容。
首先,声明一个数组和一个常量指针并指向那个数组。
int arr[3] = { 1, 2, 3 };
//声明数组
const int *p_arr =
//声明常量指针
设问:一个整型指针的长度为4Byte,比较数组名的数据长度和指针的数据长度是否相等?
printf("*p_arr的长度=%d,arr的长度=%d\n", sizeof(p_arr),sizeof(arr));
运行结果:p_arr的长度=4,arr的长度=12
结论:数组名应该不是指针。
设问:数组名不能作为左值,那常量指针呢?
p_arr = p_
运行结果:不报错
运行结果:报错&&&=&做操作数必须左值 and 表达式必须是可修改的左值。
const int *p_arr = &arr[0]; //重新声明一个,指向数组首地址 printf("p_arr的地址=%p,arr的地址=%p\n", &p_arr, &arr);
运行结果:p_arr的地址=002DF958,arr的地址=002DF964。
结论:数组名不是常量指针,更不是指向数组首地址的常量指针。
设问:常量指针能为左值,那常量呢?
const int a = 3;
运行结果:报错&&&a&不能给常量赋值 and 表达式必须是可修改的左值。
结论:常量指针不是一个常量。
设问:数组名是一个常量吗?
printf("3的地址=%p,arr的地址=%p\n", &3, &arr);
运行结果:报错&&常量上的&&& and 表达式必须为左值或者函数提示符。(数组名存在地址,而常量不存在)
#define B 5
printf("B的地址=%p,arr的地址=%p\n", &B, &arr);
运行结果:报错&&常量上的&&& and 表达式必须为左值或者函数提示符。(与上一致)
printf("a的地址=%p,arr的地址=%p\n", &a, &arr); //a是之前用const声明过的常量
运行结果:能正常运行,说明a和arr都有自己的存储空间。
a = arr[0]; //因为arr=arr[0],现在那arr[0]的值赋给a
printf("a的地址=%p,arr的地址=%p\n", &a, &arr);
运行结果:a的地址=0041F7FC,arr的地址=(二者不在同一块内存单元中)
结论:数组名不是一个常量,也不是一个用const限定变量所形成的常量。
设问:数组名是否完成等同于数组首地址?
&arr[0] = &arr[0];
运行结果:报错&&&=&做操作数必须左值 and 表达式必须是可修改的左值。(和arr =的结果一致)
printf("arr[0]的地址=%p,arr的地址=%p\n", &arr[0], &arr);
运行结果:arr[0]的地址=002FFA34,arr的地址=002FFA34。(地址完全相等)
printf("&arr的长度=%d,arr的长度=%d\n", sizeof(&arr[0]), sizeof(arr));
运行结果:&arr的长度=4,arr的长度=12。
结论:数组名应该就是数组首地址,只是当在使用sizeof运算符时,可能进行了隐式转换。(转换指代整个数组,既sizeof(arr)=数组中元素的个数 乘以 sizeof(arr[0])的值)
最后的结论:暂且认为数组名在一般情况下就是该数组的首地址,在使用sizeof运算符时,数组名指代自身数组的全部元素的地址。
本文永久更新链接地址:
相关资讯 & & &
& (05/11/:23)
& (08/14/:44)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经???读并接受上述条款

我要回帖

更多关于 听听声音 的文章

 

随机推荐