C/C++拾遗(一):关于数组的指针和数组元素首地址的一道经典题
代码例如以下:
#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++拾遗(一):关于数组的指针和数组元素首地址的一道经典题的更多相关文章
- [C++]指针和指向数组的指针[一维数组与指针]
1.一维数组与指针 形如:int型 数组 a[10] 1)&a[0] 地址常量;地址类型:int *型 ; 存储数组a的首地址 ...
- GDB调试字符数组时指针和数组区别的体现
测试ftell函数时发现报错,先贴源码 // File Name: ftell.c #include <stdio.h> #include <stdlib.h> int mai ...
- C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用
类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...
- c/c++ 函数、常量、指针和数组的关系梳理
压力才有动力,15年中旬就要准备实习,学习复习学习复习学习复习学习复习……无限循环中,好记性不如烂笔头……从数组开始,为主干. c 的array由一系列的类型相同的元素构成,数组声明包括数组元素个数和 ...
- 指针与数组的区别 —— 《C语言深度剖析》读书心得
原书很多已经写的很清楚很精炼了,我也无谓做无意义的搬运,仅把一些基础和一些我自己以前容易搞混的地方写一下. 1. 意义: 指针: 指针也是一种类型,长度为4字节,其存放的内容只能是一个地址(4字节). ...
- 【C语言入门教程】4.6 指针 和 数组
数组在内存中以顺序的形式存放,数组的第一个存储单元的地址即数组的首地址.对一维数组来说,直接引用数组名就能获得该数组的首地址.指针变量可以存放于其内容相同的数组首地址,也可以指向某一具体的数组元素.通 ...
- C语言指针与数组的定义与声明易错分析
部分摘自<C语言深度解剖> 1.定义为数组,声明为指针 在文件1中定义: char a[100]; 在文件2中声明: extern char *a; //这样是错误的 这里的extern告 ...
- c数组与指针
0.数组和指针并不是相同的 我们声明数组时,同时分配了一些内存空间,用于容纳数组元素,但是当我们声明一个指针时,只分配了用于容纳指针本身的内存空间. 从这个方面也可以理解sizeof后面跟数组名和指针 ...
- 【原创】一起学C++ 之指针、数组、指针算术 ---------C++ primer plus(第6版)
C++ Primer Plus 第6版 指针和数组基本等价的原因在于指针算术! 一.指针 ⑴整数变量+1后,其值将增加1: ⑵指针变量+1后,增加的量等于它指向的类型的字节数: ⑶C++将数组名解析为 ...
随机推荐
- Oracle解除表锁定问题
1.肯定是你同时打开了多个操作页面,要记得关闭多个打开的sql窗口. 2.可以变相删除表,再重新创建一张同名的表来解除表被锁住的问题
- linux入门基础——linux用户基础
这篇内容是linux用户基础,相关内容见linux改动username和ubuntu改动username和主机名. 用户.组 当我们使用linux时,须要以一个用户的身份登入,一个进程也须要以一个用户 ...
- [笔记][Java7并发编程实战手冊]3.4 等待多个并发事件的完毕CountDownLatch倒计数闭锁
[笔记][Java7并发编程实战手冊]系列文件夹 简单介绍 本文学习CountDownLatch 倒计数闭锁. 本人英文不好.靠机器翻译,然后有一段非常形象的描写叙述,让我把它叫为倒计数 用给定的计数 ...
- 深入浅出CChart 每日一课——快乐高四第九课 于无声处,CChart内置功能介绍之数据存取篇
笨笨长期以来一直使用Origin软件画图和处理数据,但Origin软件没有编程语言的接口.笨笨开发CChart的一个潜在的目标.是想实现Origin软件的功能.当然这是一个不可能达到的目标.Origi ...
- Quartz2D二维画图引擎
Quartz2D二维画图引擎 这个二维画图引擎的功能很强大 一般苹果公司xcode 提供给我们的一些UI控件不能满足我们的需求 所以我们会自己定义控件 xcode 提供的全部控件都是由这个画图引擎画出 ...
- 1、libgdx简单介绍
Libgdx 是一个跨平台和可视化的的开发框架.它当前支持Windows.Linux,Mac OS X.Android,IOS和HTML5作为目标平台. Libgdx同意你一次编写代码不经改动部署到多 ...
- Oracle 性能优化的基本方法
Oracle 性能优化的基本方法概述 1)设立合理的性能优化目标. 2)测量并记录当前性能. 3)确定当前Oracle性能瓶颈(Oracle等待什么.哪些SQL语句是该等待事件的成分). 4)把等待事 ...
- USACO 2.1 Healthy Holsteins
Healthy HolsteinsBurch & Kolstad Farmer John prides himself on having the healthiest dairy cows ...
- SQL 数据库性能优化
http://blog.csdn.net/yzllz001/article/details/54848513 1. 减少数据访问(减少磁盘访问) 2. 返回更少数据(减少网络传输或磁盘访问) 3. ...
- 抓取git的log文件批处理命令示例
@echoset sincedate="2016-04-28 00:00:01" ::变量set beforedate="2016-04-29 00:0 ...