C语言学过好久了,对于其中的指针却没有非常明确的认识,趁着有机会来好好学习一下,总结一下学过的知识,知识来自C语言指针详解一文

一:指针的概念

  指针是一个特殊的变量,里面存储的数值是内存里的一个地址。学好指针,重要的是搞清楚指针的四个方面的内容:指针的类型、指针所指向的类型、指针所指向的内存区、指针本身占据的内存区。

1、 如何判断指针的类型呢:

  

int *p;
char *p;
int **p;
int (*p)[3];
int *(*p)[4];

  上面的五个声明,指针的类型分别是:int *、char *、int ** 、 int (*)[3]、int *(*)[4];是不是非常简单,就是把变量名去掉,剩下的就是指针的类型。

2、指针所指向的类型

int *p;
char *p;
int **p;
int (*p)[3];
int *(*p)[4];

  上面五个声明,指针所指向的类型分别是:int\char \int *\int()[3]\int *()[4],找出规律了吗?就是把变量名和一个*去掉,剩下的就是指针所指向的类型。特别强调:指针的类型和指针所指向的类型是不同的概念。

3、指针所指向的内存区或者指针的值

  指针的值是指针本身所存储的数值,这个值被编译器当作一个地址,而不是而不是一个一般的数值。在32位程序里,所有的类型的指针的值都是一个32位数,因为32位程序中内存地址全部都是32位字长。

  指针所指向的内存区就是从指针的值所代表的内存区开始,长度为sizeof(指针所指向的类型)的一篇内存区。以后,我们说一个指针的值是XX,就代表了该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某个内存区域,相当于指针的值就是该内存区域的首地址。

  指针指向谁,就把谁的地址赋给指针。

4、指针本身所占据的内存区

  指针本身占据了多大的内存。用sizeof(指针的类型)测试一个就知道了。在32位平台里,指针本身占据了四个字节的长度。

二、指针的算术运算

  

char a[20];
int *p=a;
p++;

  指针p的类型是 int * ,指针所指向的类型是int ,它被初始化位指向整形变量a,接下来指针p被加了1,编译器是这样处理的:它把指针p的值加上了sizeof(int),在32位程序里,是加上了4.由于地址是用字节做单位的,故p的地址由原来的a的地址指向了加四个字节后的高地址。

  由于char类型的长度是一个字节,所以原来p是指向数组从0开始的四个字节,现在指向了从第四个字节开始的四个字节

  我们可以用一个指针和一个循环来遍历一个数组:

  

int arr[20];
int *p=arr;
.......//此处略去整数型赋值的代码
for(i = 0; i<20 ; i++)
{
(*p)++;
P++;
}

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

char a[20];
int *p=a;
...
...
p+=5;

  在这个例子中,p被加上了5,从编译器的角度看:将指针p的值加上sizeof(int),在32位恒旭中就是加上了5*4=20.由于地址的单位十字街,故现在p指向刚开始高字节方向的20个字节。在这个例子中,没加5之前的p指向数组第0个单元开始的四个字节,加5后,p已经指向数组的合法范围之外了。虽然这种情况在应用上会出现问题,但在语法上是可以。这体现了指针的灵活性。

  总结一下:一个指针,加上一个整数n后,结果是一个新的指针pnew,pnew的类型和pnew所指向的类型与pold的类型都是一样的。pnew的值比起pold的值增加了n*sizeof(p指向的类型)个字节。加是往高字节移动,减是往低字节移动。

三 运算符&和*

  &是取地址运算符,*在书上叫做间接运算符。&a的运算结果是一个指针,指针的类型是a的类型加一个*。指针所指向的类型是a的类型,指针所指向的地址就是a的地址。*p的结果是p所指向的结果,类型是p的类型,占用的地址就是p所指向的地址

int a =12;
int b;
int *p;
int *ptr; p=&a//&a的结果是一个指针,指针的类型是一个int *,指针所指向的数据类型是int ,指向的地址是a的地址。 *p=24;//*p的结果,它的类型是int,它所占用的地址是p所指向的地址,显然*p就是变量a *ptr=&P;//p本身就是一个指针了,对p在取地址,那么 该指针的类型是int **,指针所知下个的类型是 int * 。指针所指向的地址就是p的地址 **ptr=34;// *ptr的结果就是ptr所指向的东西。在这里是一个指针,对这个指针在做一次*运算,。结果就是一个int 类型的变量

四 指针表达式

  一个表达式的最后结果如果是一个指针,这个表达式就叫做指针表达式

  

int a ,b ;
int array[10];
int *pa; pa=&a;//指针表达式
int **ptr = &pa;//表达式
*ptr=&b;//表达式
pa=array;
pa++;//表达式 char arr[20];
char **parr =arr//如果把arr看作指针的话,arr也是指针表达式
char *str; str=*parr;//指针表达式
str=*(parr+1);//指针表达式

  由于指针表达式的结果是一个指针,所以指针表达式也需要具有指针的四个要素:指针的类型,指针所指向的类型、指针指向的内存区、指针自身占据的内存区。

  指针在左边表示赋值,指针在右边表示取值。

未完待续

C语言指针学习的更多相关文章

  1. [转]C语言指针学习经验总结浅谈

    指针是C语言的难点和重点,但指针也是C语言的灵魂 . 这篇C语言指针学习经验总结主要是我入职以来学习C指针过程中的点滴记录.文档里面就不重复书上说得很清楚的概念性东西,只把一些说得不清楚或理解起来比较 ...

  2. C语言指针学习总结

    上学的时候学习C语言,最烦的就是里面指针,可是指针也恰恰是C语言的灵魂. 最近在重温数据结构的内容,因为大多数据结构的教材都是用C语言描述的,而数据结构中也大量的用到了指针的内容,所以我就在这篇笔记中 ...

  3. (转载)c语言指针学习

    前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...

  4. c语言指针学习【转】

    前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...

  5. 1.C语言指针学习之外挂篇

    学习了c语言的指针,那么指针能做什么呢,首先,他可以写外挂 首先我们来编写一个dll,挂载到植物大战僵尸上,记住是dll,因为如果你创建一个应用程序,该应用程序是不能操作其他程序的地址的. 第一步,打 ...

  6. c语言指针学习笔记

    指针变量就是存放内存地址的变量.c语言中使用 int *pa; 的方式来定义指针. ` main() int a = 10, b=20, s, t, *pa, *pb,*pc,*pd; pa = &a ...

  7. C语言指针学习(续)

    五.数组和指针的关系 int array[10] = {0,1,2,3,4,5,6,7,8,9},value; ... ... value = array[0];//也可以写成 value = *ar ...

  8. GO语言学习(十五)Go 语言指针

    Go 语言指针 Go 语言中指针是很容易学习的,Go 语言中使用指针可以更简单的执行一些任务. 接下来让我们来一步步学习 Go 语言指针. 我们都知道,变量是一种使用方便的占位符,用于引用计算机内存地 ...

  9. 2-Linux C语言指针与内存-学习笔记

    Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标准输入输出流以及错误流管道 工具与原理 指针与内存都是c语言中的要点与难点 指针 数组 ...

随机推荐

  1. Java魔法堂:打包知识点之META-INF/MAINFEST.MF

    一.前言     通过执行形如 jar -cvf src.jar src 命令将多个.class文件打包成JAR包时,你会发现JAR包中除了src目录外还多了个MATE-INF/MAINFEST.MF ...

  2. WPF Control Hints - TabControl : 怎么修改整个tab header的margin?

    WFP里面TabControl我们可以添加多个TabItem,每个TabItem的Header就是我们常点击的tab标签.但是默认的layout行为里面,这个header是有个2个像素的margin, ...

  3. C# WinFrom 跨线程访问控件

    1.跨线程访问控件委托和类的定义 using System; using System.Windows.Forms; namespace ahwildlife.Utils { /// <summ ...

  4. 【原创】本地通过IIS设置开发的localhost网站的域名改为个性域名方法

    效果图:   操作步骤如下:  第一步: 在本地IIS上新建个网站,如下图所示      第二步,修改host文件       加配置节点如下图所示       第三步,在vs里面找到你的web项目, ...

  5. Diy页面服务端渲染解决方案

    1. 问题由来 在移动互联网电商领域,运营每天需要搭建多个促销页面来吸引用户去点击去购买,一开始程序员临时写个新页面去实现,可这些页面可以用几次就不用了,每次创建新页面去实现费时费力,而且,电商的运营 ...

  6. GridView 使用方法总结 (一)

    GridView 使用方法总结 (一) 下载全部代码 http://www.sufeinet.com/thread-431-1-1.html   原文件作者是:csdn.net的清清月儿 她的主页  ...

  7. jdbcTemplate queryForObject 查询 结果集 数量

    1.组织sql语句, 查询参数 数组, 设置返回类型 public int countByCondtion(String title, int mediaType, String currentSta ...

  8. python函数和常用模块(二),Day4

    内置函数2 装饰器 字符串格式化 生成器 迭代器 递归 模块 序列化相关 time模块 datetime模块 内置函数2 callable() # 是否可以被执行,是否可以被调用 chr() # as ...

  9. 推荐轻量友好的.NET测试断言工具Shouldly

    Shouldly是一个轻量的断言(Assertion)框架,用于补充.NET框架下的测试工具.Shouldly将焦点放在当断言失败时如何简单精准的给出很好的错误信息. Shouldly在GitHub的 ...

  10. js的alert和confirm美化

    --前言-- window对象的alert和confirm标准方法在不同浏览器的显示效果不太相同,有个相同点是都不是很美观.我们的想法是使用js和css分别仿照它们,提供另一套函数,使在不同浏览器的有 ...