首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
其他好文
> 详细
数组名的理解
时间:
2014-09-04 23:42:40
阅读:
191
评论:
0
收藏:
0
[点我收藏+]
标签:
数组名
const
数组指针
数组名的再理解
先看下面的这段代码,程序会输出什么结果?
#include <stdio.h>
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *p = (int *)(&a+1);
printf("%d %d\n", *(a+1), *(p-1));
return 0;
}
答案详见本文的最后。
先来一步步分析一下数组名到底是什么,首先看一下下面这段代码:
#include <stdio.h>
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *p;
p = a;
return 0;
}
编译和运行都没有错误,说明a的值的类型直接赋给p是可以的,至少这说明了a的类型是属于可以直接赋值给p的类型中的一种,即a应该是一个指针类型的变量,而且这个指针类型变量的绝对不是int*类型的,因为在上面的程序中如果我们输出sizeof(a)和sizeof(p)的话可以看到一个输出的是20,一个输出的是4,证明这两个类型是不一样的,程序稍作修改:
#include <stdio.h>
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *p;
a = p;
return 0;
}
编译器报错误:cannot convert from ‘int *‘ to ‘int [5]‘,然而这个int [5],C语言里并没有这种类型,这个类型其实很明显就是int a[5]把a去掉之后剩下的。暂时可以这样理解,a就代表的分配的20个字节的单元整体,同时a本身的值是这20个字节的起始地址,所以a是有两层含义的。再改一下程序:
#include <stdio.h>
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *p;
a ++;
return 0;
}
编译器报错:‘++‘ needs l-value,这个错误的意思是++需要一个可以作为左值的操作对象,++唯一能够操作的就是变量,然而a根据上面的分析就是分配的一个20字节的变量,a的值也就是这20个字节变量的首地址,然而对a进行++操作却是不可以的,这个特点跟const修饰的变量时一致的。const修饰的变量相当于被赋予了只读属性,也就是说读取是可以的,写操作是非法的,所以const修饰的变量是不能做左值的,也就是不能被重新赋值的。再次修改一下例子:
#include <stdio.h>
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *p;
p = &a;
return 0;
}
编译器报错:cannot convert from ‘int (*)[5]‘ to ‘int *‘,有了这个错误问题就越来越清晰了,对a的取地址操作得到的类型是int (*)[5],即一个数组指针,也就是说这个时候取地址操作对a的理解是一个20个字节的整体(5个int型的单元)。然而当采用p=a这种使用方法的时候,使用的是a的第二种理解方法就是取的是a的值,也就是这20个字节的起始地址。
再由C语言的优先级来分析最开始的题目,int *p = (int *)(&a+1)这条语句,&的优先级高于+,所以等同于int *p (int *)((&a)+1),这下来逐步分析,&a得到的是一个5个int型单元的数组指针,&a+1得到的就是这个指针加1的结果,也就是说现在的指针会指向a这20个字节后的第一个单元,这个单元的地址再被强制转换为int *类型赋值给p,所以p也就指向了a的20个字节后的第一个单元,所以*(p-1)取到的值就应该是p的前一个单元,也就是a的5个单元中最后的一个单元的值。所以得到最开头的程序输出为:2 5
数组名的理解
标签:
数组名
const
数组指针
原文地址:http://blog.csdn.net/laoniu_c/article/details/39062361
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
分布式事务
2021-07-29
OpenStack云平台命令行登录账户
2021-07-29
getLastRowNum()与getLastCellNum()/getPhysicalNumberOfRows()与getPhysicalNumberOfCells()
2021-07-29
【K8s概念】CSI 卷克隆
2021-07-29
vue3.0使用ant-design-vue进行按需加载原来这么简单
2021-07-29
stack栈
2021-07-29
抽奖动画 - 大转盘抽奖
2021-07-29
PPT写作技巧
2021-07-29
003-核心技术-IO模型-NIO-基于NIO群聊示例
2021-07-29
Bootstrap组件2
2021-07-29
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!