代码例如以下:

#include <stdio.h>
int main(void)
{
int a[5] = {1, 2, 3, 4, 5};
int *ptr = (int *)(&a+1);
int *p1 = a;
int *p2 = &a[0];
int *p3 = (int *)(&a); if(p1 == p2){
printf("p1 == p2\n");
}else{
printf("p1 != p2\n");
} if(p1 == p3){
printf("p1 == p3\n");
}else{
printf("p1 != p3\n");
} if(p2 == p3){
printf("p2 == p3\n");
}else{
printf("p2 != p3\n");
} printf("%d %d\n",*(a+1),*(ptr-1)); int *p4 = ++p1;
int *p5 = ++p3;
if(p4 == p5){
printf("p4 == p5\n");
}else{
printf("p4 != p5\n");
}
return 0;
}

终于输出结果例如以下:

里面全部的推断都是相等,打印的两个值是2和5.

原因例如以下:

&a是数组的首地址,它的类型是int(*)[5],因此+1是加的是数组个数的步长。

指针加1要依据指针自身类型加上一定的值。 不同类型的指针+1之后添加的大小不同

因此&a + 1后指向的地址对数组来说是越界的,注意前面有个int(*)又强制将他转为int*了。因此计算*(ptr - 1)的时候,ptr是个int类型的指针。减一等于往左移动sizeof(int*)个字节,因此又指向a[4]了。他的值等于&a[4].

为此杂家又对p4和p5作了验证。为啥结果p4会等于p5呢?原因就在于申请p3的时候对&a进行了强制类型转换。

int *p3 = (int *)(&a);

假设不加这个转换,是编译只是去的。加了转换之后p3等于p1也等于p2,他的类型跟另外两个一样都是int*类型的了。因此移动同样位后地址也是一样的。非常多人纠结就纠结在&a、a、&a[0],根本原因在于对&a进行了强制类型(int*)转换。

C/C++拾遗(一):关于数组的指针和数组元素首地址的一道经典题的更多相关文章

  1. [C++]指针和指向数组的指针[一维数组与指针]

     1.一维数组与指针      形如:int型 数组 a[10]                1)&a[0]  地址常量;地址类型:int *型   ; 存储数组a的首地址          ...

  2. GDB调试字符数组时指针和数组区别的体现

    测试ftell函数时发现报错,先贴源码 // File Name: ftell.c #include <stdio.h> #include <stdlib.h> int mai ...

  3. C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用

    类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...

  4. c/c++ 函数、常量、指针和数组的关系梳理

    压力才有动力,15年中旬就要准备实习,学习复习学习复习学习复习学习复习……无限循环中,好记性不如烂笔头……从数组开始,为主干. c 的array由一系列的类型相同的元素构成,数组声明包括数组元素个数和 ...

  5. 指针与数组的区别 —— 《C语言深度剖析》读书心得

    原书很多已经写的很清楚很精炼了,我也无谓做无意义的搬运,仅把一些基础和一些我自己以前容易搞混的地方写一下. 1. 意义: 指针: 指针也是一种类型,长度为4字节,其存放的内容只能是一个地址(4字节). ...

  6. 【C语言入门教程】4.6 指针 和 数组

    数组在内存中以顺序的形式存放,数组的第一个存储单元的地址即数组的首地址.对一维数组来说,直接引用数组名就能获得该数组的首地址.指针变量可以存放于其内容相同的数组首地址,也可以指向某一具体的数组元素.通 ...

  7. C语言指针与数组的定义与声明易错分析

    部分摘自<C语言深度解剖> 1.定义为数组,声明为指针 在文件1中定义: char a[100]; 在文件2中声明: extern char *a; //这样是错误的 这里的extern告 ...

  8. c数组与指针

    0.数组和指针并不是相同的 我们声明数组时,同时分配了一些内存空间,用于容纳数组元素,但是当我们声明一个指针时,只分配了用于容纳指针本身的内存空间. 从这个方面也可以理解sizeof后面跟数组名和指针 ...

  9. 【原创】一起学C++ 之指针、数组、指针算术 ---------C++ primer plus(第6版)

    C++ Primer Plus 第6版 指针和数组基本等价的原因在于指针算术! 一.指针 ⑴整数变量+1后,其值将增加1: ⑵指针变量+1后,增加的量等于它指向的类型的字节数: ⑶C++将数组名解析为 ...

随机推荐

  1. HDU 4767

    昨晚苦恼了一晚,因为即将大三了,必须要准备实习什么的事了.一般都会去公司实习吧,但是看看自己的简历,实在拿不出手,因为大一大二都在搞ACM(虽然真正搞的只有大二一年),但却没有什么成绩,又不愿意做项目 ...

  2. 开源APM应用性能管理工具调研

    近期在设计一个DevOps平台.希望整合一个APM工具进来,由于APM既可用于性能測试也可用于运维性能监控,是典型的Dev+Ops产品. 商业的APM工具国内外已经有不少成熟产品了,而开源的好像不多见 ...

  3. multiset多重集合容器

    跟set集合容器相比,multiset多重集合容器也使用红黑树组织元素,仅仅是multiset多重集合容器同意将反复的元素键值插入.元素的搜索依旧具有对数级的算法时间复杂度,find和equal_ra ...

  4. angularjs1-5,class,

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. Linux 下安装apache2.4

    Linux 下安装apache2.4 下载,解压,配置安装! 好生麻烦! 安装一个apache,需要很多依赖!比如apr.apr-util.pcre等等. 这些依赖有可能还需要别的更多的依赖! 真心的 ...

  6. ffmpeg x264编译与使用介绍

    问题1:我用的是最新版本的ffmpeg和x264,刚刚编译出来,编译没有问题,但是在linux 环境使用ffmpeg的库时发现报错error C3861: 'UINT64_C': identifier ...

  7. HD-ACM算法专攻系列(14)——find your present (2)

    问题描述: 源码: #include"iostream" #include"algorithm" using namespace std; bool cmp(i ...

  8. Java Servlet 配置

    图片太大,可以右键另存再查看,也可以鼠标点击拖置一下,用浏览器单独承载放大查看.

  9. Java 系列之spring学习--springmvc注解方式(五)

    一.springmvc注解方式 注解方式使用的更多,更加灵活.在上一篇的博客的基础上修改springmvc-servlet.xml配置文件. <?xml version="1.0&qu ...

  10. 03《UML大战需求分析》之三

    学习了活动图之后,我又学习了流程分析工具之二的状态机图.看上去状态机图和活动图很类似,我也很容易从活动图的角度来理解状态机图.但是学习之后,发现两种图是两种完全不同的分析角度.活动图在流程分析时是玩你 ...