指针杂例1

  先来猜猜这个最后输出结果为什么:1?2?

#include<stdio.h>
int main(void)
{
    int a[5] = {1,2,3,4,5};
    int *p = (int *)(&a+1);
    printf("%d\n",*(p-1));
    return 0;
}

  运行一下会发现,最后输出的是5。为什么呢?我们一句句看看吧;

 定义一个int型数组a,长度为5  这个应该没有什么问题。那为什么*(a+1-1)变成了5呢?其实重点在下面这一句

int *p = (int *)(&a+1);

  这一句到底做了什么?  首先定义了一个int型的指针p,然后把左边一个东西强制转换给p,那给p的到底是什么呢?

  奥妙其实在这:大家都知道,a本身已经是数组首元素的地址了,a就代表这个数组首元素的地址,也等同于一个指向该数组首元素的指针。对这个指针再取址,就成了一个指向数组的指针了,即  int (*q)[5];  故&a+1并非往后移一个sizeof(a[0])   而是移sizeof(a) * sizeof(a[0]),也就正好移到了数组的外面,然后强行把这个转成一个int类型的指针,即此时p是int类型的指针  且指向了数组最后一个元素的后面。对一个指针运算和对这个指针的二进制值运算是不同的。(大家在编译器中可以调试看看,在值运算时加1真的就是地址加1,而指针加1是依赖于本身指针的类型的)

printf("%d\n",*(p-1));

  这里p已经是int型的指针,所以对p进行操作,又是一次移动sizeof(int)的长度了,p-1正好就是指向了数组的最后一个元素,所以结果就是5.

原文地址:https://www.cnblogs.com/YaLi/p/9785832.html

时间: 2024-09-30 07:03:30

指针杂例1的相关文章

C指针典例

C指针典例 2015-03-10 李海沿 一.指针的算术运算 例一. 1. char a[20]; 2. int *ptr=a; 3. ptr++; 在上例中,指针ptr的类型是int*,它指向的类型是int,它被初始化为指向整形变量a.接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针ptr的值加上了sizeof(int),在32位程序中,是被加上了4.由于地址是用字节做单位的,故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节.由于char类型的长度是一个字节

Scheme中lambda表达式与函数指针小例

SICP/Chapter2/Exercise-2.4 Lambda表达式语法 (lambda kw-formals body) 题目描述 用过程性表示方式重写序对的cons.car.cdr Scheme代码 (define (cons-24 x y) (lambda (m) (m x y))) (define (car-24 z) (z (lambda (p q) p))) 这段代码只有4行,但是逻辑关系并不好理解. 原因在于函数式语言的自顶向下实现方式不符合一般的逻辑习惯. lambda以类似

【转】让你不再害怕指针——C指针详解(经典,非常详细)

前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧: [cpp] view plain copy int p; //这是一个普通的整型变量 int *p; //首先从P 处开始,先与*结合,所以说明P 是一个指针,

指针的本质---如何确定指针的类型

前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍 一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一 个类型里会出现很多运算符,他们也像普通的表达式一样,有优先 级,其优先级和运算优先级一样,所以我总结了一下其原则: 从变量名处起,根据运算符优先级结合,一步一步分析. 下面让我们先从简单的类型开始慢慢分析吧: int p; int *p; //这是一个普通的整型变量 //首先从 P 处开始,先与*结合,所以说明 P 是一 //个指针,然后再与 int 结合,

MFC获得主窗口和父窗口指针

MFC编程中常常遇到子窗口向父窗口传递参数的情况,这就需要获得父窗口的指针. 例:主对话框CMyMainDlg通过按钮ButtonA进入对话框CMyParentDlg,CMyParentDlg在通过按钮ButtonB进入对话框CMyChildDlg.现在需要在CMyChildDlg分别访问CMyParentDlg和CMyMainDlg的内容,需要在CMyChildDlg中加入以下两条语句: CMyMainDlg    *pMMD = (CMyMainDlg*)AfxGetMainWnd();  

[转]C 语言指针的使用

第一章 指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址. 要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的 类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区.让 我们分别说明. 先声明几个指针放着做例子: 例一: (1)int *ptr; (2)char *ptr; (3)int **ptr; (4)int (*ptr)[3]; (5)int *(*ptr)[4]; 如果看不懂后几个例子的话,请参阅我前段时间贴出的文?lt;<如何

指向指针的指针

理解二级指针,关键是理解指针的存储方式和意义. 这里以指向int型指针的指针为例,梳理一下二级指针在内存分配中 的奥妙.... #include <iostream> using namespace std; int main() { int a[5] = {1, 2, 3, 4, 5}; int *p = a; int **point = &p; cout << "a = " << a << endl << &quo

C指针的解析

这是我从网上转载的一篇关于C指针的文章,方便自己以后回顾,自己添加修改部分内容 ,不对请指正 Attention:指针是指针变量 ,数组是指针常量 第一章 指针的概念  指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址. 要搞清一个指针需要搞清指针的四方面的内容: (1)指针的类型 (2)指针所指向的类型 (3)指针的值或者叫指针所指向的内存区 (4)指针本身所占据的内存区. 先声明几个指针放着做例子: 例一: (1) int *ptr; (2) char *ptr; (3) i

C++Study 指针详解

C++指针详解 指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区.让我们分别说明. 先声明几个指针放着做例子: 例一: int *ptr; char *ptr; int **ptr; int (*ptr)[3]; int *(*ptr)[4]; 指针的类型 从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类