指针数组和数组指针问题

指针问题(指针数组,数组指针,二级指针)
标签:日用百货&居家日用&表
浏览数:378
i++) { for(j=0,2两行输出顺序,p[i][j]);J& p=a;i&!;%d\\,{222}; } 可以将数组输出来;3;)!!;n&!;3!, 222 111 333 用改变指针指向的方法,{333}} int *p[3];t&,结果 111 222 333 现在想要改变1!; printf(& for(i=0!!;j++) printf(&,求大神指导int a[3][3]={{111}
你好!我是瑞明&名品水杯生产厂家电商部,现在想寻找合适的代理分销合作,我们支持一件代发,产品是以中性无logo包装,支持定制logo,定制自己品牌,提供产品质量认证,https://rmingpin.1688.com,期待您的光临。活动赠品广告促销批发实用礼品水杯tritan水壶水瓶柠檬杯 茶水分离杯,安全锤杯,双功能运动新款静态数组的动态指针数组的问题。。。我都不知道怎么说了— —!
[问题点数:40分,结帖人richiexieqing]
静态数组的动态指针数组的问题。。。我都不知道怎么说了— —!
[问题点数:40分,结帖人richiexieqing]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
匿名用户不能发表回复!|【c/c++】指针数组和数组指针
实例放在最上面的,这个能全部看懂,下面的知识也就不要再往下看的。如果不行,那么就好好看下去然后回来温习这个实例
#include&iostream&
#include&string.h&
char * cp = &hello world&;
cout && cp &&
//输出“hello world”
cout && *cp &&
//输出h单个字符
这个结果和之前char a[10],直接是cout&&a,结果是整个字符数组.但是别的类型的数组,其结果是首地址。
char *max(char *ps[], int n);
int main(){
char *s[5] = { &aaa&, &bbb&, &ccc&, &ddd&, &ccs& };
char(*q)[3];
p = max(s, 5);
//q = max(s,5);这样的出错原因是指针指向的类型不一样,前者是数组,后者是字符,因此出错
//*p的时候只出现一个值d,p的时候结果是ddd;要了解原因
//首先看到指针p定义最后指向的是一个字符,因此*p最后的结果肯定是单个字符,不是我们想要字符串
cout && &the max string:& && *p &&
cout && &the max string:& && p &&
char * max(char *ps[], int n){
//这样会报错,说不能将char**赋值给char*,也就是说指针数组的数组名不能像正常数组那样进行赋值,而是要用数组的第一个元素吗?
//这里终于明白了为什么ps不可以,而ps[0]就可以了。虽然ps是数组名可以代表首地址,但是你想想ps指向的数据类型是数组,而ps指向的数据类型是指针
//这样当然是不可以赋值的,指针指向的类型的不同就不同进行赋值操作
//那为什么ps[0]就可以呢,它不是一维数组吗,p=&a[0].那这里为什么不加取地址符啊,你看看之前a[0]存储的是数据,而这里的ps[0]里面
//存储是指针,也就是说ps[0]也是指针变量,最后指向的类型也是相同的,因此是可以赋值的。
q = ps[0];
for (int i = 0; i & i++){
//看strcmp的源代码定义:int
__cdecl strcmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2);
if (strcmp(q, ps[i]) & 0)
q = ps[i];
1、指针数组和数组指针的内存布局
指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。
数组指针:首先它是一个指针,它指向一个数组。在32 位系统下永远是占4 个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”的简称。
下面到底哪个是数组指针,哪个是指针数组呢:
int *p1[10];
int (*p2)[10];
这里需要明白一个符号之间的优先级问题。
“[]”的优先级比“*”要高。p1 先与“[]”结合,构成一个数组的定义,数组名为p1,int *修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含10 个指向int 类型数据的指针,即指针数组。至于p2 就更好理解了,在这里“()”的优先级比“[]”高,“*”号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2 是一个指针,它指向一个包含10 个int 类型数据的数组,即数组指针。我们可以借助下面的图加深理解:
2.论a 和&a 之间的区别
既然这样,那问题就来了。前面我们讲过a 和&a 之间的区别,现在再来看看下面的代码:
int main()
& &char a[5]={'A','B','C','D'};
& &char (*p3)[5] = &a;
& &char (*p4)[5] =
& &return 0;
上面对p3 和p4 的使用,哪个正确呢?p3+1 的值会是什么?p4+1 的值又会是什么?毫无疑问,p3 和p4 都是数组指针,指向的是整个数组。&a 是整个数组的首地址,a是数组首元素的首地址,其值相同但意义不同。在C 语言里,赋值符号“=”号两边的数据类型必须是相同的,如果不同需要显示或隐式的类型转换。p3 这个定义的“=”号两边的数据类型完全一致,而p4 这个定义的“=”号两边的数据类型就不一致了。左边的类型是指向整个数组的指针,右边的数据类型是指向单个字符的指针。在Visual
C++6.0 上给出如下警告:
& &warning C4047: 'initializing' : 'char (*)[5]' differs in levels of indirection from 'char *'。
还好,这里虽然给出了警告,但由于&a 和a 的值一样,而变量作为右值时编译器只是取变量的值,所以运行并没有什么问题。但是在最新的c++14中已经禁止这样写代码了,因此下面例子中关于p4+1这种情况就就不分析了
既然现在清楚了p3 和p4 都是指向整个数组的,那p3+1 和p4+1 的值就很好理解了。
#include &iostream&
int main() {
char a[5] = { 'A', 'B', 'C', 'D' };
char(*p3)[10] = &a;
// char (*p4)[5] =
cout && a &&
cout && &a &&
cout && p3 &&
cout && p3 + 1 &&
输出结果:ABCD
// 0xbfdf79fb
// 0xbfdf79fb
// 0xbfdf7a00
加一也就说加一整个字符数组的长度,即5个字节
//现在疑惑点来了,是用cout输出数组名的时候 居然能够直接输出数组中的内容而不是其首地址
//字符数组是可以用这种方式输出的, 因为数组名即代表首地址, 数组是一块连续的内存空间, 所以能直接输出.
//如果是其他类型的数组则输出的是一个地址.
int b[2] = {1,12};
cout&&b&&//这个时候输出的还真的是一个地址
这里有一个问题就是将char(*p3)[5]中的5改成别的数字可以吗?答案是肯定的,结果是程序出错,不允许运行
3.地址将强制类型转换
struct Test
& &char *pcN
& &short sD
& &char cha[2];
& &short sBa[4];
假设p 的值为0x100000。如下表表达式的值分别为多少?
& &p + 0x1 = 0x___ ?
& &(unsigned long)p + 0x1 = 0x___?
& &(unsigned int*)p + 0x1 = 0x___?
我相信会有很多人一开始没看明白这个问题是什么意思。其实我们再仔细看看,这个知识点似曾相识。一个指针变量与一个整数相加减,到底该怎么解析呢?
还记得前面我们的表达式“a+1”与“&a+1”之间的区别吗?其实这里也一样。指针变量与一个整数相加减并不是用指针变量里的地址直接加减这个整数。这个整数的单位不是byte 而是元素的个数。所以:p + 0x1 的值为0x;sizof(Test)*0x1。这个就好比地址对数字的加减运算是和数据类型是相关联的,只不过现在是换成结构体了
至于此结构体的大小为20byte,前面的章节已经详细讲解过。有边界补充,因此按照最大存储的字节乘以数量
所以p +0x1 的值为:0x100014。
(unsigned long)p + 0x1 的值呢?这里涉及到强制转换,将指针变量p 保存的值强制转换成无符号的长整型数。任何数值一旦被强制转换,其类型就改变了。所以这个表达式其实就是一个无符号的长整型数加上另一个整数。所以其值为:0x100001。
(unsigned int*)p + 0x1 的值呢?这里的p 被强制转换成一个指向无符号整型的指针。所以其值为:0x;sizof(unsigned int)*0x1,等于0x100004。当指针指向的数据类型发生变化,那么其关联数据类型基本单位存储大小也已经发生改变,因此,这里我们计算的基本单位的存储单元大小是要发生变化的。
首先去看指针指向数据的存储大小是多少,接着看地址要移动的数据大小是多少。然后相乘的结果加上原先的地址就是最后的结果。当然如果像中间的数据变换了,例如上面将其变为长整型的数据,那么你加减的结果就是常规的数据加减了
上面这个问题似乎还没啥技术含量,下面就来个有技术含量的:在x86 系统下,其值为多少?
& &int a[4]={1,2,3,4};
& &int *ptr1=(int *)(&a+1);
& &int *ptr2=(int *)((int)a+1);
& &printf(&%x,%x&,ptr1[-1],*ptr2);
& &return 0;
如果懂汇编,这道题目很简单
根据上面的讲解,&a+1 与a+1 的区别已经清楚。
ptr1:将&a+1 的值强制转换成int*类型,赋值给int* 类型的变量ptr,ptr1 肯定指到数组a 的下一个int 类型数据了。ptr1[-1]被解析成*(ptr1-1),即ptr1 往后退4 个byte。所以其值为0x4。
ptr2:按照上面的讲解,(int)a+1 的值是元素a[0]的第二个字节的地址。然后把这个地址强制转换成int*类型的值赋给ptr2,也就是说*ptr2 的值应该为元素a[0]的第二个字节开始的连续4 个byte 的内容。
其内存布局如下图:
好,问题就来了,这连续4 个byte 里到底存了什么东西呢?也就是说元素a[0],a[1]里面的值到底怎么存储的。这就涉及到系统的大小端模式了,如果懂汇编的话,这根本就不是问题。既然不知道当前系统是什么模式,那就得想办法测试。大小端模式与测试的方法在第一章讲解union 关键字时已经详细讨论过了,请翻到彼处参看,这里就不再详述。我们可以用下面这个函数来测试当前系统的模式。
int checkSystem( )
& &union check
& &c.i = 1;
& &return (c.ch ==1);
如果当前系统为大端模式这个函数返回0;如果为小端模式,函数返回1。也就是说如果此函数的返回值为1 的话,*ptr2 的值为0x2000000。如果此函数的返回值为0 的话,*ptr2 的值为0x100。
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?探讨C语言中的指针和数组问题_论文_百度文库
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
探讨C语言中的指针和数组问题
中国最大最早的专业内容网站|
总评分0.0|
&&针对C语言中的两大重点内容,结合实例,探讨了指针和数组在解决某些问题上的等价性,对不同层次和不同类型的C语言开发人员中有一定的指导意义。
试读已结束,如果需要继续阅读或下载,敬请购买
定制HR最喜欢的简历
你可能喜欢指针数组的问题,地址为什么一样呢? - 知乎45被浏览<strong class="NumberBoard-itemValue" title="分享邀请回答int a[4];
-+---------------------------
-----------------------------
| a[0] | a[1] | a[2] | a[3] |
int* p = &a[0]; // equivalent to a
------------------------
------------------------
数组是其成员的集合,如图所示。所以a的地址和a[0]的地址一样,都是用+标识的字节的地址。而p的地址和a[0]的地址就相差十万八千里了。那么为什么这么容易产生混乱呢?因为C中的数组,在大多数情况下会转换为指向第一个元素的指针:a -& &a[0]
因此大多数情况下数组a的行为看起来像指针。但是这个“大多数情况”不包括&a,sizeof a,等等。所以说“数组就是第一个元素的地址”是很滑稽的——第一,把指针当成地址;第二,完全忽略例外情况的存在;第三,完全忽略存储的情况。当然说“没有物理意义”或者“a和&a都是XXX的地址”就更滑稽了。以上。2037 条评论分享收藏感谢收起

我要回帖

更多关于 指针数组 的文章

 

随机推荐