C语言-指针
C指针基础知识
C语言中,指针无疑是最令人头疼的。今天无事就来学学C语言的指针,在此留下点笔记,仅供个人参考。
首先要搞懂的是,指针是什么?
指针:是用来存放内存地址的变量。
不管是什么类型的指针,存放的都是内存地址,所有类型的指针变量的大小都是一致的。
和指针相关的两个符号: & 取址符。取一个变量的地址。 * 表示一个指针,同时也可以取指针对应的变量的值。
下面来看一下指针最简单的使用。
代码上解释的比较清楚了,来看看打印的结果,前两行打印的结果是一样的,所以可以看出,指针里面存放的就是变量i的地址。
看打印结果的后面两行,可以看出。这两行的结果都是3,倒数第二行打印出来的就比较好理解了,是变量i的值,也就是3;打印结果的最后一样,也是3,*pi 表示取指针变量 pi 存储的地址所对应的变量的值。
说起来有点绕,反正,记住,指针是地址,而 *pi 是取值,取该指针对应的变量的值。
这个例子中,有一点需要明白的是:不论改变i的值还是 pi 的值,都不会互相影响。
也就是说,改变了i的值,pi 的值是不会变的,这个好理解,我只是改变了这个变量的值,而我这个变量依然在内存中,还是在那块内存中,所以,只要这i的在内存中的位置(地址)不变,pi 的值就不会变。
同时,改变了 pi 的值,i 的值也是不会变的,例如现在多了一个 int 类型的 j 变量,然后把 j 变量的地址赋给 pi,那么只是改变了 pi 的值,pi 里面存放的是变量j的地址,而变量i的地址和值都不会发生任何改变。
这也就是指针的灵活性,指针可以指向该指针对应的类型的任意变量。(说白了就是 --> pi 能指向任何 int 类型的变量,不能指向其他类型的变量)
下面再来看一个简单的例子,交换两个数字。
如果不使用指针的话,很简单,直接搞一个中间变量,就可以交换这两个变量的值了。而使用指针的话,也很简单,照葫芦画瓢嘛。
上面注释掉的是不用指针的时候,一清二楚,不用说都明白了。
下面是使用指针的情况,都说照葫芦画瓢了,既然指针 pi 存放的是变量 i 的地址,那么,*pi 就表示变量 i 的值,那么就好办了,在前面的代码中,用 *pi 替代掉 i 不就好了么,同样的道理,用 *pj 替代掉 j 就好了。
最后来看一下下面两个方法,这两个方法是一点更要搞懂的,不然你说我知道什么是指针。那就是扯蛋。
假设我现在不在主函数里面交换两个变量 i j 的值,而是调用一个方法去交换他们的值,现在该调用哪个方法呢?
很简单嘛,两个都一样,既然传进去的是int类型的值,那么就直接取指针变量对应的值不就得了,也就是这样:swap( *pi , *pj );
而调用第二个的时候就是 swap( pi , pj );
没错,方法调用是没错的,是这样调用。但能够使值交换的,只有下面这个方法,道理也很简单:
先看上面方法那个代码,方法体中的 x y 都是局部变量,这个方法改变的只是局部变量的值。而主函数里面的确没有改变。所以,这个函数是不能交换其值的.(这也就是值传递)
再来看下面这个方法,下面这个方法是可以,下面方法为什么可以呢?因为传递的是地址。为啥传递的地址就可以?
这个嘛,举个例子。怎么举例呢?居然这个涉及到了内存,那么就举一个看起来吻合一点的例子吧!
有两个房子,地址分别是人民路1号和人民路8号,1号房子里面存放着一个篮球,8号房子里面存放着一个足球。
第一个方法,就好像直接把球复制出来。把复制品去交换,也就是值得传递,而第二个方法则传的是两个房子的地址,跟你说要把两个房子里面的球交换一下。然后你就跑去1号房子,把球抱出来,然后跑到8号房子,交换球,再把球拿回到1号房子。就这么简单。这就是引用传递。
小结:
如何让子函数更改主函数的值?
1:子函数的形参为一个地址的值。
2:子函数去修改形参的地址所对应的变量的值。
3:主函数在使用的时候把要修改的变量的值传递给子函数。
指针常见的错误:
1:指针变量在没有赋值之前不能使用。
没有赋值,也就是垃圾值,在编程上就叫野指针;
2:类型不同的指针不能互相转换。
3:使用指针的时候,不去访问已经被系统回收的数据。
子函数执行完毕后,子函数的所有局部变量都会被系统回收,如果能够获取到值,那都是影子值,是不能确保该值的正确性;
指针还有一个比较灵活的使用,在java中,返回值可以是基本类型,也可以是对象,也可以容器类(数组,集合等),但在C中是不允许返回数组的。那么,我们使用指针可以返回2个以上的参数。
怎么返回呢?很简单啊,既然容器类可以装多个变量,而C中是没有集合的,那就是数组了呗,数组又要返回一个,怎么返回呢?直接返回数组的地址不就好了么!
指针的运算:
指针其实也可以像其他变量一样运算。
开什么玩笑,指针也可以计算,指针不是地址么?两个地址运算的结果是什么?例如拿上面那个例子,人民路1号和人民路8号,运算的结果是啥?难道是人民路9号?
没错,你说对了,指针当然不能直接的使用地址进行加减乘除,地址的加减乘除是没有任何意义也不允许这样子做的。
既然不能使用指针去进行加减乘除,那么我们在每一个指针前面加个*,也就是取指针的值进行运算不就得了,没错,这也是对的。
但;这是指针的运算么,这是指针所对应的值的运算,好吧!
既然说是指针的运算,那就是指针的运算,来看下面这个例子:
这个就是一个指针运算的例子,看最后两行的打印语句,变量i不就是指针变量么,指针变量+1和-1不就是指针的运算么?
可以看到的是:打印的第一行,取指针 i 所对应的值,也就是数组arr下标为2的值(数组中第三个,也就是3).
上面这点搞明白了就好办了,指针+1和-1表示取这个指针变量相邻的地址所对应的值。这句话怎么理解呢?也就是说,+1表示取这个位置的下一个,而-1表示取上一个,这个比较好理解。
但它是怎么取得呢?怎么去识别的呢?一个int里面是4个字节。是怎么会自动的向上或向下偏移4个字节的呢?
别忘了,指针也是有数据类型的,虽然指针里面存放的都是地址,但这个地址只能存该指针相对应的变量的地址,所以,指针在运算偏移的时候就会根据指针自身对应的变量的长度来进行偏移。
多级指针
说白了,就是指针的指针,其中可以有N层,哈哈。
假设有这样一段代码:
int i=5;
int* pi=&i;
int** ppi=π
第一行很好理解了,第二行我们也知道是什么意思了,接下来看第三行;
第三行就是指针的指针,也就是说,里面存放的是指针的地址,这个怎么理解呢,第二行很好理解吧,指针变量存放的是 int 类型变量i的地址,同样的道理,既然变量i是在内存中存在的,那么变量 pi 也是在内存中实际存在的,所以,变量 pi 也是有地址的,这里存放的就是指针 pi 的地址。其实就好像你去找人,我要去找张三,结果我去到教室。张三不在,同学说张三去了宿舍(一级指针),然后我跑会宿舍,同学说张三在饭堂(二级指针)。如果饭堂没找到,那就是三级指针了。哈哈
这个搞清楚了,接下来就好办了。还是上面这个例子:
pi 里面存放的变量i的地址,那么,*pi 就是取变量i的值,而ppi存放的是 pi 的地址,那么 *ppi 其实取到的就是 pi 的值(变量i的地址),那么要通过 ppi 去取变量i的值,那么就要使用 **ppi 了。这个比较好理解,上面这个理解清楚下面的就好理解了。
最后说一点:函数的指针
指针不仅可以是变量的指针,指针的指针,还可以是函数的指针。同理,函数的指针存放的是个函数的地址。
看代码:
这就是一个函数的指针的简单的示例代码,代码里面注释也写的比较清楚了。
这里需要注意的是,函数必须写在main函数之前,因为函数必须要先装载进内存,才能知道函数的地址是啥,否则会报错。
指针基础只是就写到这里:
2016-10-18 21:30
C语言-指针的更多相关文章
- C语言指针转换为intptr_t类型
1.前言 今天在看代码时,发现将之一个指针赋值给一个intptr_t类型的变量.由于之前没有见过intptr_t这样数据类型,凭感觉认为intptr_t是int类型的指针.感觉很奇怪,为何要将一个指针 ...
- [转]C语言指针学习经验总结浅谈
指针是C语言的难点和重点,但指针也是C语言的灵魂 . 这篇C语言指针学习经验总结主要是我入职以来学习C指针过程中的点滴记录.文档里面就不重复书上说得很清楚的概念性东西,只把一些说得不清楚或理解起来比较 ...
- 不可或缺 Windows Native (7) - C 语言: 指针
[源码下载] 不可或缺 Windows Native (7) - C 语言: 指针 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 指针 示例cPointer.h #i ...
- C语言指针学习
C语言学过好久了,对于其中的指针却没有非常明确的认识,趁着有机会来好好学习一下,总结一下学过的知识,知识来自C语言指针详解一文 一:指针的概念 指针是一个特殊的变量,里面存储的数值是内存里的一个地址. ...
- (转载)c语言指针学习
前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...
- 关于C语言指针的问题
在学习关于C语言指针的时候,发现这样一个问题,代码如下: #include<stdio.h> #include<stdlib.h> #include<string.h&g ...
- C语言指针类型 强制转换
关于C语言指针类型 强制转换 引用一篇文章: C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值.不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个 ...
- C语言指针和数组知识总结(上)
C语言指针和数组知识总结(上) 一.指针的基础 1.C语言中,变量的值能够通过指针来改变,打印指针的语句符号可以是: %08x 2.指针的本质 指针的本质就是变量,那么既然是变量,那么一定会分配地址 ...
- C语言指针操作
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/pointer-manipulation. ...
- C语言指针声明探秘
C语言指针声明探秘
随机推荐
- python27 ImportError: No module named site
运行 python27 时发现 提示这个错误 在http://stackoverflow.com/questions/5599872/python-windows-importerror-no-mod ...
- mac rvm升级ruby
rvm是什么?为什么要安装rvm呢,因为rvm可以让你拥有多个版本的Ruby,并且可以在多个版本之间自由切换.第一步:安装rvm $ curl -L get.rvm.io | bash -s stab ...
- ubuntu 安装phpstorm
1.清除 sudo apt-get purge openjdk* 2.添加源及更新源列表 sudo add-apt-repository ppa:webupd8team/java sudo apt-g ...
- Solr DIH JDBC 源码解析
Solr DIH 源码解析 DataImportHandler.handleRequestBody()中的importer.runCmd(requestParams, sw) if (DataImpo ...
- 『AngularJS』$location 服务
项目中关于 $location的用法 简介 $location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用.改变在地址栏中的URL会作用到$loc ...
- 一些比较实用的css片段
新看了一个帖子,里面好多实用的css代码块,可拿出来当做功能库.先附上该文地址http://segmentfault.com/a/1190000002773955 里面的内容很多我挑了几个经过我验证的 ...
- c++书
http://www.enet.com.cn/eschool/video/c++/ 视频 http://www.runoob.com/cplusplus/cpp-inheritance.html ...
- bootstrap之HTML模板
bootstrap之HTML模板 <!DOCTYPE html> <html> <head> <title>Bootstrap 模板</title ...
- linux install mysql
sudo apt-get install mysql-server #此处会输入root的密码,设置的密码要记住 sudo apt-get install mysql-client sudo apt- ...
- 问题2: 安装cocoaPods出现的一系列问题
在新电脑上安装cocoaPods的时候,出现了一系列的问题,现在记录下来,方便查看 1.出现 Invalid mark letter (press RETURN) 解决方案:输入 :wq 即可 2. ...