对程序进行编译的时候,系统会把变量分配在内存单位中,根据不同的变量类型,分配不同的字节大小。比如int整型变量分配4个字节,char字符型变量分配1个字节等等。被分配在内存的变量,可以通过地址去找到,内存区每一个字节都有一个编号,地址也可以形象的理解成我们生活中的住址,通过住址找到每一个人所在的地方。指针作为一个变量用来存放地址,可以通过指针来改动变量。

上图就是一个简单的定义一个一级指针变量和利用指针改变变量数值的过程。int*表示整型指针,*p表示解引用操作,就是利用指针找到a的地址然后再改变a的值。

地址用%p打印,用十六进制表示,在打印时候输入指针变量p和取地址a得出的结果是相同的,证明了指针是用来存放地址的。

指针作为一个变量是有大小的,其大小在32位平台是4个字节,64位平台上是8个字节,大小与指针的类型无关。

上图以32位平台举例子,可以看到无论指针是整型、字符型、浮点型也无论一级指针还是二级指针,其在内存空间所占的大小都是4个字节。

指针有多种类别,按照级数来分便可以分为一级指针,二级指针,三级指针等等

一级指针是最基础的指针,指向的是创建的变量的地址。就类似于上图的前三个sizeof后面所写的。前文讲到指针也是一个变量,是用来存放地址的。既然是一个变量,就也要在内存开辟空间,开辟了空间就也会产生属于指针变量自己的地址。二级指针便是用来存放一级指针地址的。以此类推多级指针也是如此。

指针也可以根据指针指向的变量的数据类型来进行分类,有整型指针,字符指针,数组指针,函数指针等等

整型指针和字符指针

这两个是比较常见和容易理解的指针,依次用int*和char*表示,他们的区别在于指向变量类型不同,内存也不一样,在进行解引用操作时访问的字节大小也因为变量类型的区别会有所差异。整型指针可以访问4个字节,而字符指针只能访问1个字节。也就是说对整型指针变量解引用,一次可以操作一个整型,而对字符变量解引用一次只能操作一个字符。

较为特殊的char*p="hello"这并不是将整个字符串的地址传个了p,而是传了字符穿首元素‘h'的地址,可以通过'h‘的地址来找到整个字符串。此时出现char*p2=“hello”,p2和p代表的是同一处地址,因为hello是常量字符串,没有必要开辟两块不同的空间的来存储它。这是字符指针的一个特性。

void型指针

void型的指针可以接受任何类型的地址,但是不能对void型指针进行解引用操作。解引用操作要有特定的访问字节的数量,比如对整型指针解引用就是访问4个字节,字符型指针解引用就是访问1个字节,而void型指针无法确定访问字节个数,所以不能进行解引用操作。同时void*这种类型的指针也不能进行加减整数的操作,因为无法确定跳过的字节个数。

此图表示了void型指针可以接受任意类型的地址。

数组指针

这是一种指向数组的指针,例如int(*p)[10]这就是一个指向数组的指针,它指向的数组有10个元素,每个元素都是整型。给*p加上括号是因为p和[10]优先结合,这样的话就变成了一个数组而不是指针了。这个数组叫指针数组,int*p[10]这样的写法意思是一个有10个元素的数组,每一个元素都是整型指针,这和数组指针是两个不同的东西。

指向数组的指针里面存放的便是数组的地址,而非数组某个元素的地址,所以在定义数组指针时要用 &+数组名,而不是简单使用 数组名。

上图显示出&arr和arr的不同,虽然起始地址相同,但arr+1只让指针向后移动了一个元素的空间,而&arr+1让指针移动了一个数组的空间。

函数指针

函数指针顾名思义就是指向函数的指针,每个函数都有一个入口,这个入口的地址便是函数指针所指向的地址。函数地址的表示方法为 函数名或 &+函数名。例如一个函数叫Add,&Add和Add都是表示这个函数的地址没有什么差别。函数指针的写法是 函数的返回类型(*)(函数的参数),例如函数Add,其函数指针的写法就是int(*p)(int,int)=Add 。*p要加上括号来保证*和p的优先结合来形成一个指针变量,如果不加括号来优先结合,则会出现int* p(int,int)这样的写法,这就变成了函数的声明,这个函数的返回类型是int*,函数的名字叫p,函数的参数是2个整型和原先的函数指针不是同一个意思。

用函数指针调用函数时可以不加*这个解引用符号,因为这个符号将不会在程序运行的时候起到作用。

上图显示了*这个解引用符号在函数指针调用函数时候不起作用,以上的写法都可以用。

根据函数指针的相关知识,可以来看这两段代码。

代码1中间的 void(*)()是一个函数指针类型,将这个函数指针类型放在括号中,是强制类型转换的意思也就是把0强制转换成一个函数指针,强制类型转换这个部分简单写出来就是“(函数指针)0”是将0作为一个函数的地址,而最外层的括号(*函数的地址)()这个是解引用操作,也就是通过0这个地址,找到了0地址处所在的函数,并且进行调用。

代码2 内部的(int,void(*)(int))这一段表示的函数的参数,第一个参数是一个整型,第二个参数是一个函数指针类型,这个函数指针指向的函数的返回类型是void,参数类型是int。而这个函数的名字就是signal。解决了这个部分的内容,剩下的就是void(*)(int),去除里面的signal函数可以很明显地看出来这是一个函数指针。一个函数由三部分组成,返回类型,函数名,函数的参数。也就是说参数和函数名去掉之后,函数声明中就只剩下一个返回类型。此时,函数名和参数已经在前一步分析中得出,剩下的void(*)(int)便就是函数的返回类型,这个函数返回类型是也是一个函数指针。

这两个代码来自于书本《C陷阱和缺陷》。

函数指针和数组的结合实例,简易的计算器,这是函数指针数组的应用

数组传参

数组在传参的时候传的是首元素的地址,数组名表示首元素的地址。函数的形参可以用数组形式表示也可以用指针形式表示。

一维数组的传参比较简单,例如int arr[3]这个数组,形参可以直接使用int arr[]或者int arr[3]用数组形式表示形参,形参处的元素个数可以写也可以不写,因为元素个数在这里不起作用。或者用一级指针表示,int* arr这样就反映了指针传参传的是首元素地址。

二维数组传参相对比较复杂,由数组的知识可以知道,二维数组必须有规定的列数,所以要以数组形式传参的时候列数不能省略。

以指针形式传参,数组名仍然是首元素地址的意思,作为一个二维数组,首元素便是第一行的数组。比如int arr[3][5]这个二维数组的首元素是一个含有5个整型元素的数组,所以在传参的时候传的指针也应该是指向这个数组的指针。所以此时形参应该表示为int (*arr)[5],这表示一个数组指针,指向一个含有5个整型元素的数组,符合正确的传参规则。

回调函数

回调函数是把函数指针作为参数传给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由函数实现方直接调用,而是用另外一方或者特定条件下来调用。

比较常见的例子就是C语言里面的库函数快速排序,这里需要自己实现的比较函数,就用到了回调函数,int_cmp作为函数的指针充当了qsort的参数。

模拟实现qsort快速排序函数,冒泡排序的推广

到此这篇关于C语言指针基本知识实例讲解的文章就介绍到这了,更多相关C语言指针基本知识内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

c语言中字符指针变量输入,C语言指针基础知识实例讲解相关推荐

  1. c语言中字符型变量的类型标识符是,C语言中类型标识符有哪些

    满意答案 564vlaci 2015.10.29 采纳率:48%    等级:12 已帮助:6409人 C语言中的标识符 1) 标识符由字母.数字.下划线"_"组成,并且首字母不能 ...

  2. c语言中向计算机输入,C语言中字符数据的输入和输出

    字符的输出 C语言中使用putchar函数来输出字符数据 #include int main() { char a,b,c,d; //定义字符变量a,b,c,d a = 'F'; b = 'U'; c ...

  3. C语言中字符型变量与整型变量的联系

    1)字符型变量可以与整型变量一样进行算术运算(使用字符数据的ASCII码值进行运算的) 例1: char m = 'A'; char n = 32; //char类型直接赋值整型,此整型为对应字符的A ...

  4. c语言 字符型变量,C语言中字符型变量与整型变量的联系

    1)字符型变量可以与整型变量一样进行算术运算(使用字符数据的ASCII码值进行运算的) 例1: char  m = 'A'; char  n = 32;     //char类型直接赋值整型,此整型为 ...

  5. A13在c语言中是合法变量吗,C语言中局部变量和全局变量等在内存中的存放位置.doc-资源下载在线文库www.lddoc.cn...

    C语言中局部变量和全局变量_等在内存中的存放位置.doc C 语言中局部变量和全局变量 变量的存储类别static,extern,auto,register 8.8 局部变量和全局变量在讨论函数的形参 ...

  6. c语言中字符 12是多少,c语言中字符串的讲解(DOC可编).doc

    c语言中字符串的讲解(DOC可编).doc 第一部分:字符串的概念 ---字符串:用双引号引起来的一串字符.在C语言,系统将自动的为字符串添加一个结束标志\0 ,该结束标志不作为字符串的实际长度,但作 ...

  7. c语言中字符占用的存储单元,C语言知识点第1章.doc

    C语言知识点第1章 C语言知识点总结(二) 第八节 字符字符常量定义:一对单引号括起来的一个字符.如'A'.'a'.'9'相应字符对应的ASCII编码值(见附录四)字符常量占用一个字节的存储单元(一个 ...

  8. suma在c语言中表示什么变量,大学C语言程序设计考试试题及答案3套.doc

    <大学C语言程序设计考试试题及答案3套.doc>由会员分享,可在线阅读,更多相关<大学C语言程序设计考试试题及答案3套.doc(18页珍藏版)>请在装配图网上搜索. 1.C语言 ...

  9. c语言中字符进行按位与,c语言位运算符的用法

    C语言中位运算的运算分量只能是整型或字符型数据,位运算把运算对象看作是由二进位组成的位串信息,按位完成指定的运算,得到位串信息的结果.下面小编就为大家介绍下c语言位运算符的用法. c语言位运算符的用法 ...

最新文章

  1. Linux中shell的介绍
  2. hihocoder #1329 : 平衡树·Splay
  3. java获得电脑性能_Java:使用SingletonStream获得性能
  4. Dubbo Zookeeper Quick Start
  5. python字符串怎么表示_python中字符串的几种表达方式(用什么方式表示字符串)...
  6. 晨哥真有料丨Ta是暧昧成瘾,你却动了真心!
  7. [BZOJ1563][NOI2009]诗人小G[决策单调性优化]
  8. Oracle之pl/sql编程(一)函数,过程,包
  9. Codeforces Bubble Cup 8 - Finals [Online Mirror] B. Bribes lca
  10. 最火的开源项目及编程语言
  11. 这个大学时代的博客不在维护了,请移步到我的新博客
  12. 黑苹果EFI|联想 Lenovo ideapad 320S-15IKB 笔记本电脑实战黑苹果
  13. HTML5+CSS3 为图书简介页面添加图像及视频
  14. 批处理访问服务器共享文件夹,批处理设置文件访问权限的方法分享
  15. ERP软件厂商薪资情况披露
  16. 分布式数据库设计——分布式数据库的基础概念
  17. ELK环境部署(一)--基础环境配置
  18. 生物信息常用文件格式
  19. case zhen语句_SQL中的条件判断语句(case when zhen if,ifnull)用法
  20. springboot+rocketmq(5):实现批量消息

热门文章

  1. 云计算技术-HCIA之VLAN及总结
  2. 【Python】【进阶篇】十六、Python爬虫的浏览器实现抓包
  3. 卷积神经网络及YOLO算法 相关
  4. 帽子设计作品——蒸汽朋克的乌托邦,机械配件的幻想世界!
  5. 用户行为分析案例——天池数据集User Behavior Data from Taobao
  6. 人工智能数学基础---不定积分4:有理函数求积分的方法
  7. 六年级下册计算机电子板报教案,电子工业出版社六年级下册信息技术全册教案.doc...
  8. 克隆别人的qq空间?
  9. C++枚举算法之和数
  10. c语言编程循环结构加EOF语句练习