C语言中的精华是什么,答曰指针,这也是C语言中唯一的难点。
C是对底层操作非常方便的语言,而底层操作中用到最多的就是指针,以后从事嵌入式开发的朋友们,指针将陪伴我们终身。
本文将从八个常见的方面来透视C语言中的指针,当然,还有其他没有具体提到的方面,像指针表达式、指针安全等问题,以后有机会我再慢慢补充。
还是那句老话,重要的是实践,多写代码,才是学好C语言的关键。
1.指针类型分析
分析指针,可以从变量名处起,根据运算符优先级结合,一步一步分析.
int p; //这是一个普通的整型变量
int *p; //首先从P处开始,先与*结合,所以说明P是一个指针,然后再与int结合,说明指针所指向的内容的类型为int 型.所以 P是一个返回整型数据的指针
int p[3]; //首先从P处开始,先与[]结合,说明P 是一个数组,然后与int结合,说明数组里的元素是整型的,所以 P是一个由整型数据组成的数组
int *p[3]; //首先从P处开始,先与[]结合,因为其优先级比*高,所以P是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与 int结合,说明指针所指向的内容的类型是整型的,所以是一个由返回整型数据的指针所组成的数组
int (*p)[3]; //首先从P处开始,先与*结合,说明P是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.所以P是一个指向由整型数据组成的数组的指针
int **p; //首先从 P开始,先与*结合,说明P是一个指针,然后再与*结合,说明指针所指向的元素是指针,然后再与 int结合,说明该指针所指向的元素是整型数据. 所以P是一个返回指向整型数据的指针的指针
int p(int); //从P处起,先与()结合,说明P是一个函数,然后进入()里分析,说明该函数有一个整型变量的参数然后再与外面的int 结合,说明函数的返回值是一个整型数据.所以P是一个有整型参数且返回类型为整型的函数
int (*p)(int); //从P处开始,先与指针结合,说明P是一个指针,然后与()结合,说明指针指向的是一个函数,然后再与()里的int 结合,说明函数有一个int 型的参数,再与最外层的int 结合,说明函数的返回类型是整型,所以P是一个指向有一个整型参数且返回类型为整型的函数的指针
int *(*p(int))[3]; //从 P开始,先与()结合,说明P是一个函数,然后进入()里面,与int结合,说明函数有一个整型变量参数,然后再与外面的*结合,说明函数返回的是一个指针,,然后到最外面一层,先与[]结合,说明返回的指针指向的是一个数组,然后再与*结合,说明数组里的元素是指针,然后再与int 结合,说明指针指向的内容是整型数据.所以P是一个参数为一个整数且返回一个指向由整型指针变量组成的数组的指针变量的函数
2.指针分析
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
要搞清一个指针需要搞清指针的四方面的内容:指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。
指针的类型:把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型
指针所指向的类型:把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型(在指针的算术运算中,指针所指向的类型有很大的作用)
指针所指向的内存区:从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。(一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址)
指针本身所占据的内存区:用函数sizeof(指针的类型)可以测出指针本身所占据的内存区(在 32位平台里,指针本身占据了 4个字节的长度)
3.指针的算术运算
指针和整数进行加减:一个指针 ptrold加(减)一个整数 n后,结果是一个新的指针ptrnew,ptrnew 的类型和 ptrold 的类型相同,ptrnew 所指向的类型和 ptrold所指向的类型也相同,ptrnew的值将比 ptrold 的值增加(减少)了n乘sizeof(ptrold所指向的类型)个字节。
指针和指针进行加减:两个指针不能进行加法运算,这是非法操作;两个指针可以进行减法操作,但必须类型相同,一般用在数组方面。
4. 运算符&和*
&是取地址运算符,*是间接运算符。
&a的运算结果是一个指针,指针的类型是a的类型加个*,指针所指向的类型是a的类型,指针所指向的地址嘛,那就是a的地址。
*p的运算结果就五花八门了,总之*p 的结果是 p 所指向的东西,这个东西有这些特点:它的类型是 p指向的类型,它所占用的地址是p所指向的地址。
5. 数组和指针的关系
数组的数组名其实可以看作一个指针。
声明了一个数组 TYPE array[n],则数组名称array就有了两重含义:
第一,它代表整个数组,它的类型是 TYPE[n];
第二 ,它是一个常量指针,该指针的类型是TYPE*,该指针指向的类型是 TYPE,也就是数组单元的类型,该指针指向的内存区就是数组第0号单元,该指针自己占有单独的内存区,注意它和数组第0号单元占据的内存区是不同的。该指针的值是不能修改的,即类似 array++的表达式是错误的。
6. 指针和结构类型的关系
假设我们定义了一个结构体,struct MyStruct{inta;int b;int c;};
同时定义结构体的结构对象并初始化,struct MyStructss={20,30,40};
那么我们如何通过指针ptr 来访问 ss的三个成员变量呢?
答案就是,我们先定义一个指向结构对象 ss的指针,struct MyStruct *ptr=&ss; 然后,使用指向运算符->便可实现对结构对象ss成员的访问。
ptr->a; //或者可以这们(*ptr).a,建议使用前者
ptr->b;
ptr->c;
7. 指针和函数的关系
可以把一个指针声明成为一个指向函数的指针,从而通过函数指针调用函数。让我们举一个例子来说明以下吧。
int fun(char *,int);
int (*pfun)(char *,int);
pfun=fun;
int a=(*pfun)("abcdefg",7);
例中,定义了一个指向函数fun的指针pfun,把pfun作为函数的形参。把指针表达式作为实参,从而实现了对函数fun的调用。
8. 指针类型转换
当我们初始化一个指针或给一个指针赋值时,赋值号的左边是一个指针,赋值号的右边是一个指针表达式,这就要求两边的类型一致,所指向的类型也一致,如果不一致的话,需要进行强制类型转换。语法格式是:(TYPE *)p;
这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE *,它指向的类型是TYPE,它指向的地址就是原指针指向的地址。要注意的是,原来的指针p的一切属性都没有被修改。
另外,一个函数如果使用了指针作为形参, 那么在函数调用语句的实参和形参的结合过程中,也必须保证类型一致 ,否则需要强制转换。
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语言指针声明探秘
随机推荐
-
解决Maven项目pom.xml文件报xxx\target\classes\META-INF\MANIFEST.MF (系统找不到指定的路径。)问题
最近自己在公司项目修改一些代码以后,出现如题的错误,后来各种Google等,最终找到了解决办法. 错误环境:Tomcat7 + Eclipse + Maven + Spring + SpringMvc ...
-
webapp应用---cordova.js 3.7.0插件安装总结
今天是2014年的最后一天,年终总结什么的就不写了.记录一下今天的工作内容.如果不知道phoneGap,那么就不需要往下看了,phoneGap现在已经叫cordova了,叫什么不重要,重要的是它对we ...
-
UITableView 接口的调用顺序
ios7启用estimatedHeightForRowAtIndexPath之后的api调用顺序called -[XHYTableViewController tableView:heightForR ...
-
[WebStrom] Change default cmd to Cygwin
GO to setting, search Terminal: Change shell path : C:\cygwin\bin\bash.exe --login -i (to the loc ...
-
查看android进程信息
打开adb shell.直接ps命令 假设查看某特定进程,比方<圣火英雄传>.用grep过滤 各列參数意义: USER 进程当前用户: PID Pro ...
-
内存管理pbuf.h头文件源码解析——LwIP学习
声明:个人所写所有博客均为自己在学习中的记录与感想,或为在学习中总结他人学习成果,但因本人才疏学浅,如果大家在阅读过程中发现错误,欢迎大家指正. LwIP的内核(core文件夹)文件中pbuf.c是包 ...
-
Spring Boot 系列教程18-itext导出pdf下载
Java操作pdf框架 iText是一个能够快速产生PDF文件的java类库.iText的java类对于那些要产生包含文本,表格,图形的只读文档是很有用的.它的类库尤其与java Servlet有很好 ...
-
二十二、oracle pl/sql分类二 函数
函数用于返回特定的数据,当建立函数时,在函数头部必须包含return子句.而在函数体内必须包含return语句返回的数据.我们可以使用create function来建立函数. 1).接下来通过一个案 ...
-
APP软件半成品测试技巧
由于现在产品类型的多样性,产品功能的先进性,更多体现在产品质量的稳定性和可靠性.软件应用的领域不断深入,设计的复杂程度逐步扩大,开发的周期不断缩短,质量的要求就逐渐提高.然而根据我们公司的版本迭代速度 ...
-
python3.6新特性
print(f'{6:^30}') print('\n'.join([' '.join([f'{i}*{j}={i*j:2d}' for j in range(1,i+1)]) for i in ra ...