首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
编程语言
> 详细
C语言指针——指针和数组
时间:
2014-09-26 11:14:08
阅读:
193
评论:
0
收藏:
0
[点我收藏+]
标签:
c语言
指针
数组
先看一个常用的例子:
#include <stdio.h>
int main(void)
{
int a[3] = {1,2,3};
int *p = a;
printf("%d ", p[0]);
return 0;
}
这段代码编译和运行都没有任何问题,程序会打印出1这个值,但是为什么可以这样用呢?p明明是一个int类型的指针,这里怎么可以使用p[0]这种数组的操作呢?而且我们使用sizeof去测试a和p得到的一个是a数组的大小,一个是p指针的大小,这两个类型是不一样的。其实这个是C语言内部的原因,一个指针变量在使用类似p[]这样的运算的时候,编译器内部相当于对p做了一次类型提升,将p其提升为该类型的数组,注意这里仅仅会提升一次哦!看下面的例子:
#include <stdio.h>
int main(void)
{
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int *p = (int *)a;
printf("%d ", p[0]);
return 0;
}
首先需要注意的是,(int *)这个是必不可少的,因为int型二维数组的首地址是不能直接赋值给int *变量的。其次这段代码也是可以正常输出1的,这个程序的理解跟上一个类似。再看下面一个代码:
#include <stdio.h>
int main(void)
{
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int *p = (int *)a;
printf("%d ", p[0][0]);
return 0;
}
这段代码编译或者运行的时候会出错吗?答案是编译的时候会报错,因为p是一个int类型的指针,使用[]这种运算的时候编译器会将其提升一次,仅仅是一次,所以p最多会被提升到一维数组的程度,然而这里的p[0][0]这样的操作显然是针对二维数组的,编译器不允许这样的用法。再看下面的例子:
#include <stdio.h>
int main(void)
{
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int (*p)[3] = a;
printf("%d ", p[0][0]);
return 0;
}
注意这个例子,编译和运行都不会出错,因为p是一个数组指针,a直接赋值给p也不会出错,这里也说明,数组在给该类型的指针赋值的时候,编译器默认最多降一级,也就是说一维数组给指针直接赋值编译器允许,二维数组给该类型的数组指针赋值编译器允许,但是跨过两级就不行了,就像上一个例子。同时从这里也可以看出,p[0][0]这样的操作是允许的,p被提升为二维数组,p也是被提升了一级。这段代码会打印出1。再看下面的例子:
#include <stdio.h>
int main(void)
{
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int (*p)[3] = a;
printf("%d ", p[1]-p[0]);
return 0;
}
这段代码的编译和运行都没有出错,打印的值是多少呢?首先来分析一下这个程序,p[1]中的p表示的是一个数组指针,然而使用p[]这种操作,p会被提升一级成为一个二维数组的形式,那么p[1]就相当于a[1],p[0]就相当于a[0],那么a[1]-a[0]的值是多少呢?a[1]是二维数组a中第二个[3]一维数组的首地址,而a[0]是a中第一个[3]一维数组的首地址,所以两个首地址之间相差sizeof(int)*3,然而由于这里是指针(地址)的运算,所以这里的值应该是(sizeof(int)*3)/sizeof(int),所以最终的输出结果为3。再看下面的代码:
#include <stdio.h>
int main(void)
{
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int (*p)[3] = a;
printf("%d ", *p[0]);
return 0;
}
这段代码会输出什么呢?答案是输出1。首先需要知道的是[]运算的优先级高于*运算符,然后p[0]代表的是a[0]也就是第一个一维数组的首地址,然后使用*(地址)这种写法的时候,取的是这个地址的值,所以也就是a[0][0]的值,因为a[0]=&a[0][0]。再看下面的例子:
#include <stdio.h>
int main(void)
{
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int (*p)[3] = a;
printf("%d ", *(p+1)[0]);
return 0;
}
这段代码会输出什么呢?答案是4。首先p是一个数组指针,所以p+1的运算对应过去编译器理解是指到下一个一维数组的首地址,所以p+1实际上的值为p+1*sizeof(int)*3,后面的理解就跟上面的相同了。
C语言指针——指针和数组
标签:
c语言
指针
数组
原文地址:http://blog.csdn.net/laoniu_c/article/details/39576281
踩
(
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)
周排行
更多
Spring Cloud 从入门到精通(一)Nacos 服务中心初探
2021-07-29
基础的排序算法
2021-07-29
SpringBoot|常用配置介绍
2021-07-29
关于 .NET 与 JAVA 在 JIT 编译上的一些差异
2021-07-29
C语言常用函数-toupper()将字符转换为大写英文字母函数
2021-07-29
《手把手教你》系列技巧篇(十)-java+ selenium自动化测试-元素定位大法之By class name(详细教程)
2021-07-28
4-1 YAML配置文件 注入 JavaBean中
2021-07-28
【python】 用来将对象持久化的 pickle 模块
2021-07-28
马拉车算法
2021-07-28
用Python进行冒泡排序
2021-07-28
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!