代码例如以下:

#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. NEFU 117

    可以用素数定理来解决. 素数定理:小于n的素数个数记为p(n),则随着n的增长,p(n)/(n/ln(n))=1. #include <iostream> #include <mat ...

  2. UI组件之AdapterView及其子类(三)Spinner控件具体解释

    Spinner提供了从一个数据集合中高速选择一项值的办法. 默认情况下Spinner显示的是当前选择的值.点击Spinner会弹出一个包括全部可选值的dropdown菜单或者一个dialog对话框,从 ...

  3. HDU 5045 DP+状压

    2014 ACM/ICPC Asia Regional Shanghai Online 给出N个人做M道题的正确率,每道题仅仅能由一个人做出,而且当全部人都做出来且仅做出一道题时,做过题的人才干够继续 ...

  4. HDU 1754(线段树区间最值)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. iOS_第3方类库MBprogressHUD

    1,将下载好的第3方类库MBprogressHUD源代码包增加到project(事实上就是一个.h和.m文件) 2,进入project的Build Phases,将源代码包里面的所有.m文件所有加入到 ...

  6. POJ 2796 / UVA 1619 Feel Good 扫描法

    Feel Good   Description Bill is developing a new mathematical theory for human emotions. His recent ...

  7. BZOJ 1786 DP

    思路: 肯定从小往大填合适了 f[i][j]表示第i个数是j的最少逆序对数 f[i][j]=min(f[i-1][k]+cost,f[i][j]) 优化一下成O(nk)就好啦~ (不优化也可以过的-) ...

  8. jQuery在多个div中,删除指定项

    之前工作中有一个需求,就是在一堆图片列表中,点击具体的图片,并从界面移除:点击具体的图片,下载:这是一个思路 <style type="text/css" media=&qu ...

  9. Android设计模式——工厂方法模式

    1.定义:工厂方法模式就是定义一个用于创建对象的接口,让子类决定实例化哪个类. 2.看代码: 产品抽象类 public abstract class Product { /** * 产品类抽象方法 * ...

  10. ddk安装失败后的处理

    7600.16385.1版本的DDK,在xp的本上死活按不上,怎么办呢?自己就把其他机器上安装的DDK目录,拷贝过来. 怎么建编译环境呢? 查看x86 Checked Build Environmen ...