指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。 要搞清一个指针需要搞清指针的四方面的内容:

  1. 指针的类型,
  2. 指针所指向的 类型,
  3. 指针的值或者叫指针所指向的内存区,
  4. 还有指针本身所占据的内存区。

让我们分别说明。

先声明几个指针放着做例子: 
  例一: 
  (1)int *ptr; 
  (2)char *ptr; 
  (3)int **ptr; 
  (4)int(*ptr)[3]; 
  (5)int*(*ptr)[4];

指针的类型 

  从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型: 
  (1)int*ptr;//指针的类型是int* 
  (2)char*ptr;//指针的类型是char* 
  (3)int**ptr;//指针的类型是int** 
  (4)int(*ptr)[3];//指针的类型是int(*)[3] 
  (5)int*(*ptr)[4];//指针的类型是int*(*)[4] 
  怎么样?找出指针的类型的方法是不是很简单?

指针所指向的类型 

  当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器把那片内存区里的内容当做什么来看待。 
  从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。例如: 
  (1)int*ptr;//指针所指向的类型是int 
  (2)char*ptr;//指针所指向的的类型是char 
  (3)int**ptr;//指针所指向的的类型是int* 
  (4)int(*ptr)[3];//指针所指向的的类型是int()[3] 
  (5)int*(*ptr)[4];//指针所指向的的类型是int*()[4] 
  在指针的算术运算中,指针所指向的类型有很大的作用。 

  指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C越来越熟悉时,你会发现,把与指针搅和在一起的 "类型 "这个概念分成 "指针的类型 "和 "指针所指向的类型 "两个概念,是精通指针的关键点之一。我看了不少书,发现有些写得差的书中,就把指针的这两个概念搅在一起了,所以看起书来前后矛盾,越看越糊涂。

指针的值,或者叫指针所指向的内存区或地址 

  指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。 指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。

  指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。

  以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里?

指针本身所占据的内存区

  指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。

  指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。 


指针的算术运算 


指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的。例如: 
  例二: 
  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类型的长度是一个字节,所以,原来ptr是指向数组a的第0号单元开始的四个字节,此时指向了数组a中从第4号单元开始的四个字节。 

我们可以用一个指针和一个循环来遍历一个数组,看例子: 
  例三: 
int  array[20]; 
int *ptr = array; 
... 
//此处略去为整型数组赋值的代码。 
... 
for(i=0;i <20;i++) 

 (*ptr)++; 
 ptr++; 

  这个例子将整型数组中各个单元的值加1。由于每次循环都将指针ptr加1,所以每次循环都能访问数组的下一个单元。

例四:

  1、char a[20]; 
  2、int *ptr = a; 
  ... 
  ... 
  3、ptr += 5; 
  在这个例子中,ptr被加上了5,编译器是这样处理的:将指针ptr的值加上5乘sizeof(int),在32位程序中就是加上了5乘4=20。由于地址的单位是字节,故现在的ptr所指向的地址比起加5后的ptr所指向的地址来说,向高地址方向移动了20个字节。在这个例子中,没加5前的ptr指向数组a的第0号单元开始的四个字节,加5后,ptr已经指向了数组a的合法范围之外了。虽然这种情况在应用上会出问题,但在语法上却是可以的。这也体现出了指针的灵活性。

c语言中,指针加1的情况.指针变量详细介绍的更多相关文章

  1. C语言中的memset函数和数组指针

    代码: #include <iostream> #include <cstring> using namespace std; int main(){ ] = {}; mems ...

  2. C-C++到底支不支持VLA以及两种语言中const的区别

    C-C++到底支不支持VLA以及两种语言中const的区别 到底支不支持VLA VLA就是variable-length array,也就是变长数组. 最近写程序的时候无意间发现,gcc中竟然支持下面 ...

  3. C语言中setjmp与longjmp学习笔记

    C语言中setjmp与longjmp学习笔记 一.基础介绍 头文件:#include<setjmp.h> 原型:  int setjmp(jmp_buf envbuf) ,然而longjm ...

  4. C语言中volatile的作用和使用方法

    在程序设计中,尤其是在C语言.C++.C#和Java语言中,使用volatile关键字声明的变量或对象通常具有与优化.多线程相关的特殊属性. 通常,volatile关键字用来阻止(伪)编译器认为的无法 ...

  5. C语言中的extern关键字用法

    在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”. 1. extern修饰变量的声明.举例来说,如果文件a.c需要引用b.c中变量int v ...

  6. C语言中extern的用法--转

    http://blog.sina.com.cn/s/blog_52deb9d50100ml6y.html 在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的, ...

  7. C语言中qsort函数用法

    C语言中qsort函数用法-示例分析    本文实例汇总介绍了C语言中qsort函数用法,包括针对各种数据类型参数的排序,非常具有实用价值非常具有实用价值. 分享给大家供大家参考.C语言中的qsort ...

  8. [转] C++指针加整数、两个指针相减的问题

    http://blog.csdn.net/onlyou930/article/details/6725051 说来惭愧,写C++有一段时间了.这个问题从来没有认真考虑过,此次标记于此: 考虑如下问题: ...

  9. C语言中file文件指针概念及其操作 (转载)

    文件 文件的基本概念 所谓"文件"是指一组相关数据的有序集合. 这个数据集有一个名称,叫做文件名.实际上在前面的各章中我们已经多次使用了文件,例如源程序文件.目标文件.可执行文件. ...

随机推荐

  1. com.genuitec.runtime.generic.jee60 is not defined 导入项目的异常

    系统加载工程后,报错Target runtime com.genuitec.runtime.generic.jee60 is not defined,在发布工程的同事电脑上正常 新导入的工程,出问题很 ...

  2. qs.js - 更好的处理url参数

    第一次接触 qs 这个库,是在使用axios时,用于给post方法编码,在使用过程中,接触到了一些不同的用法,写在这里分享一下. qs.parse qs.parse 方法可以把一段格式化的字符串转换为 ...

  3. scikit-learn使用PCA降维小结

    本文在主成分分析(PCA)原理总结和用scikit-learn学习主成分分析(PCA)的内容基础上做了一些笔记和补充,强调了我认为重要的部分,其中一些细节不再赘述. Jupiter notebook版 ...

  4. c++ Dynamic Memory (part 2)

    Don't use get to initialize or assign another smart pointer. The code that use the return from get c ...

  5. 第六次作业psp

    psp 进度条 代码累积折线图 博文累积折线图 psp饼状图

  6. 20135208 JAVA第四次实验

    课程:Java程序与设计     班级:1352 姓名:贺邦 小组成员: 20135212池彬宁 20135208贺邦 学号:20135208 成绩:             指导教师:娄嘉鹏     ...

  7. c# dictionnary根据value查找对应的key

    属性方法中并没有包含此功能,因此需要自己自定义一个方法: string regionName = ""; if (ControlForm.swichLanguage.Contain ...

  8. KNN算法之图像处理一

    KNN: 1.数据挖掘分类技术中最简单的方法之一. 2.也称为邻近算法,K最近邻分类算法 3.每个样本都可以用它最接近的k个邻居来代表 4.一般,距离使用欧式距离或曼哈顿距离(通常,k≤20) pyt ...

  9. Docker 入门 到部署Web 程序- (阿里面试常用的docker命令和优点)

    最近阿里的面试官问我Docker是做什么用的,我记得之前360和美团,京东的都问过,但是一直没时间看,最近有时间了,系统的学习了一下Docker,在此做一下记录,方便各位看官学习交流 一.Docker ...

  10. 【bzoj5147】casino 区间dp

    题目描述 赌城拉斯维加斯的米高梅大赌场最近推出了一种新式赌法.它的玩法是由庄家设局(所用赌具是一批五颜六色的筹码),赌徒只要交付一定数额的赌资即可入局.开赌前庄家将手中的筹码依次排开铺成一排构成一局, ...