学习笔记11-C语言-指针

什么是指针:

指针是一种特护的数据类型,使用它可以定义指针变量,指针变量存储的是整型数据,代表内存的编号,通过这个编号可以访问到对应内存。

为什么使用指针

1、函数与函数之间是相互独立的,但是有些时候需要共享变量传参是单向值传递全局变量容易命名冲突使用数组还需要传递长度函数的命名空间是相互独立的,但是地址空间是同一个,所以指针可以解决这个问题
2、由于函数传参是值传递(内存拷贝),对于字节数较多的变量,值传递的效率较低,如果传递的是变量的地址,只需要传递4|8字节,根据32|64位决定
3、堆内存无法取名,它不像stack、bss、data让变量名与内存建立联系,只能使用指针来记录堆内存的地址编号从而使用该堆内存。

如何使用指针:

定义: 类型* 变量名_p;   int* p;1、由于指针变量与普通变量的用法上有很大的区别,为了以示区分,建议在变量名后面加上_p2、指针的类型表示该指针变量存储的是什么类型变量的地址,指针的类型决定了可以通过指针变量访问的字节数3、一个*只能定义一个指针变量int a1,a2,a3;int* p1,p2,p3;//p1指针,p2,p3是intint *p1,*p2,*p3;//p1,p2,p3都是指针变量4、指针变量与普通变量一样的是随机的默认值,一般初始化为NULL(空值)。赋值(引用):变量名_p = 地址;//地址必须是有权限而且有意义的内存地址指向栈内存:int num;int* p = NULL;p = #指向堆内存:int* p = NULL;p = malloc(4);解引用: *p通过指针变量中记录的内存编号来访问对应的内存,该过程可能产生段错误。但是原因是因为存储了非法的内存编号注意:访问的字节数是由指针变量的类型决定的。*p=1000;

练习1:实现一个变量交换函数,调用它对一个数组进行排序

#include<stdio.h>void swap(int* p1,int* p2)
{int change=0;change=*p1;*p1=*p2;*p2=change;
}int main(int argc,const char* argv[])
{int num[10]={8,0,5,6,9,3,2,7,4,1};for(int i=0;i<9;i++){for(int j=i+1;j<10;j++){if(num[i]<=num[j])swap(&num[i],&num[j]);}}for(int i=0;i<10;i++){printf("%d",num[i]);}}

练习2:实现一个函数,计算两个整数的最大公约数、最小公倍数,最大公约数用return返回,最小公倍数使用指针返回
注意:想要获取多个返回值,可以借助指针返回

#include<stdio.h>int big(int n1,int n2)
{int a=n1>n2?n1:n2,b=n1>n2?n2:n1,c=1;while(c){c=a%b;a=b;b=c;}return a;
}int small(int n1,int n2)
{int a=n1>n2?n1:n2,b=n1>n2?n2:n1;int i=1;while(a*i%b!=0){i++;}return a*i;
}int max_min(int n1,int n2,int* p)
{*p=small(n1,n2);return big(n1,n2);
}int main(int argc,const char* argv[])
{int max=0,min=0;int num1,num2;printf("请输入两个数:");scanf("%d%d",&num1,&num2);max=max_min(num1,num2,&min);printf("%d %d\n",max,min);
}

使用指针需要注意的问题:

空指针:值是NULL的指针变量都是空指针,如果对空指针进行解引用产生段错误。一般NULL也是一种错误标志,如果一个函数返回值是指针类型时,当函数执行出错可以返回NULL表示该函数执行出错。注意:NULL在绝大多数的系统中都是0,在个别系统上是1if(NULL==p)if(!p)如何避免空指针带来的段错误:使用来历不明的指针之前先做判断是不是空指针。1、当函数的参数是指针时,别人传给你的就有可能使空指针2、从函数获取返回值使,也可能获取到的使空指针野指针:指针指向不确定的内存的指针野指针解引用的危害:1、脏数据2、段错误3、一切正常野指针的危害比空指针更严重,因为野指针无法判断出来,而且可能是隐藏性的错误,短时间内不暴露所有的野指针都是人为制造的,如和避免产生野指针:1、定义指针是一定要初始化2、函数不返回局部变量地址3、指针指向的内存被释放后,指针变量立即置空=NULL    

指针的运算:

指针变量里存储的是整型,理论上整型数据能使用的运算符她都能用,但绝大多数都是无意义的。指针+n:指针+指针类型的宽度*n(int就是 4)   前进了n个元素
指针-n:指针-指针类型的宽度*n               后退了n个元素
指针-指针:(指针-指针)/指针类型宽度        计算相隔了多少个这种元素

指针与const:

const int* p;
当我们为了提高传参效率而使用指针时,传参的效率虽然提高了,但是变量也有被修改的风险,这种写法就可以保护指针变量指向的内存不被修改int const *p;   效果同上
int* const p;   保护指针变量不被修改const int* const p;   保护指针变量和指针变量指向的内存不被修改
int const * const p;   效果同上const保护谁按照就近原则

指针数组与数组指针:

指针数组:由指针组成的数组,它的成员都是指针变量类型* arr[长度];数组指针:专门指向数组的指针类型 (*arr)[长度];

指针与数组名:

数组名是一种特殊的指针,它是常量,不能改变它的值,它与数组内存是映射关系,没有自己的内存空间
数组名 == &数组名 == &数组名[0]指针变量它由自己的存储空间,如果它存储的是数组的首地址,指针可以当作数组使用数组名[i] == *(数组名+i)*(指针名+i) == 指针名[i]注意:数组作为函数的参数时蜕变成了指针,所以长度丢失了。

二级指针:

二级指针就是指向指针的指针。里面存储是指针变量的地址。
定义:类型** 变量名_pp;
赋值:变量名_pp = 地址;变量名_pp = &指针变量;
解引用:*变量名_pp <=> 指针变量 p**变量名_pp <=> *指针变量 *p注意:当函数之间需要共享指针变量是必须传递二级指针

函数指针:

函数返回值 (*函数指针名p)(参数列表);函数名就是一个地址(整数),它代表了函数在代码段中的位置可以通过函数指针,把函数作为参数传递给另一个函数,这叫回调函数指针就是指向函数的指针,里面存储的就是该函数在代码段中的位置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443456.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习笔记12-C语言-堆内存、字符串

什么是堆内存&#xff1a; 是进程中的一个内存段&#xff08;text\data\bss\heap\stack&#xff09;&#xff0c;由程序猿手动控制。 特点是足够大&#xff0c;缺点是使用麻烦为什么要使用堆内存&#xff1a; 1、随着程序的复杂&#xff0c;数据会越来越多。 2、其他的内存段…

学习笔记13-C语言-字符串函数、缓冲区

字符串的常用函数: #include<string.h> size_t strlen(const char* s); 功能&#xff1a;计算字符串长度&#xff0c;但是结果不包括\0 返回值&#xff1a;返回字符串中字符的个数size_t str_len(const char* str) {assert(NULL ! str);const char* tmp str;while(*tmp…

Oracle数据库里面查询字符串类型的字段不为空和为空的SQL语句:

摘要&#xff1a;近期项目中&#xff0c;在做高级查询的时候有个条件是根据选择的字段&#xff0c;然后再选择字段的值为空和不为空做查询&#xff0c;在写SQL语句的时候费了很长时间&#xff0c;现在记录一下&#xff0c;方便日后查看&#xff1a; 一&#xff1a;查询字符串类…

学习笔记14-C语言-小项目-通讯录

通讯录&#xff1a; 要求&#xff1a; 姓名&#xff0c;性别、电话&#xff0c;最多储存50个联系人 功能&#xff1a;1、添加联系人2、按名字删除联系人3、按姓名修改联系人信息4、查找联系人&#xff0c;可通过电话&#xff0c;名字查找&#xff0c;支持模糊查找5、显示所有联…

学习笔记15-C语言-预处理指令、条件编译、头文件

预处理指令&#xff1a; 程序猿编写的代码不是标准C代码&#xff0c;并不能被真正的编译器索编译&#xff0c;需要一段程序把代码翻译一下。 翻译的过程叫做预处理&#xff0c;被翻译的代码叫做预处理指令&#xff0c;以#开头的都是预处理指令查看预处理的过程&#xff1a;gcc…

学习笔记16-C语言-小项目-使用Makefile完成2048

Makefile: Makefile是一系列编译指令组成的可执行文本&#xff0c;也叫做编译脚本。 在终端执行make命令会自动执行Makefile脚本中的编译命令&#xff0c; 而且它还可以根据文件的最后修改时间来判断哪些文件是否需要重新编译、哪些文件不需要重新编译&#xff0c;从而大大提高…

学习笔记17-C语言-结构、联合、枚举

结构&#xff1a; struct 结构是由程序猿自己设计的一种数据类型&#xff0c;用于描述一个事务的各项数据&#xff0c;由若干个不同的基础数据类型组成。设计结构&#xff1a;struct 结构体名{类型 成员名&#xff1b;...}&#xff1b;定义结构体变量struct 结构体名 变量名&a…

Maven 3.0.5 安装和配置:

摘要&#xff1a;现在的Web项目越来越多的都用maven管理了&#xff0c;所以我也抽时间学习学习&#xff0c;为了赶上时代&#xff01; 一&#xff1a;首先到maven官网&#xff1a;http://maven.apache.org/&#xff0c;然后选择相应的版本下载&#xff0c;我这里下载的是maven…

学习笔记18-C语言-文件

文件的分类&#xff1a; 文本文件&#xff1a; 存储的是ASCII码值的二进制 二进制文件&#xff1a; 存储的是数据的补码文件IO&#xff1a; FILE *fopen(const char *path, const char *mode); 功能&#xff1a;打开或者创建文件 path&#xff1a;文件的路径 mode&#x…

使用INNER JOIN ON 多表关联查询,获取指定用户下指定权限的资源SQL:

摘要&#xff1a;最近在看一个开源框架&#xff0c;其中用户&#xff0c;角色&#xff0c;资源&#xff0c;这块我感觉比较重要&#xff0c;所以就自己也模仿着写了下&#xff0c;其中在获取指定用户下的权限资源的时候遇到问题了&#xff0c;开始时&#xff0c;我首先想到的方…

Maven学习记录之maven基本操作命令,maven本地工厂的创建,maven骨架的生成,以及在eclipse中创建maven工程:...

摘要&#xff1a;今天又学习了一下maven&#xff0c;之前是下载并安装和配置好了maven的环境&#xff0c;今天主要学习的内容包括&#xff1a;maven本地工厂的创建&#xff0c;maven骨架的生成命令&#xff0c;maven在dos下创建maven工程&#xff0c;以及在eclipse中创建mavne工…

Oracle中通过游标执行带参数的存储过程实现解析CLOB字段内的xml字符串:

摘要&#xff1a;近来之前的项目数据出现了问题&#xff0c;原因是由于之前在设计数据库的时候把时间字段设置成了字符串格式&#xff0c;所以给后期的数据操作带来了很大的麻烦&#xff0c;这里提醒一下各位程序猿&#xff0c;以后在开发项目的时候时间字段一定要是时间字段&a…

Eclipse中使用Checkstyle,checkstyle插件检查java代码的自定义配置文件:

摘要&#xff1a;近来项目组在搞代码检查&#xff0c;所以领导让把checkstyle这个插件搞明白&#xff0c;现在我把我们写的自定义的checkstyle.xml文件记录一下&#xff0c;以便大家可以一起使用&#xff1a; 一&#xff1a;要使用checkstyle插件在eclipse中检查java代码&…

Linux 下安装 jdk-7u75-linux-x64.gz,jdk1.7.0_75,jdk1.7步骤:

摘要&#xff1a;近来又用到了Linux系统&#xff0c;所以就又新装了一个虚拟机和CentOS 6.4来用&#xff0c;搞开发的程序猿们可能都知道&#xff0c;在现在的很多企业中&#xff0c;生产环境大多都是Linux服务器&#xff0c;并且用的比较多的大都是CentOS&#xff0c;Red hat系…

Win7+VMware10.0+CentOS 6.4+Tomcat,Win7访问不了CentOS6.4上的Tomcat

摘要&#xff1a;今天在linux下安装Tomcat后&#xff0c;在虚拟机本地通过:http://localhost:8080/可以访问安装好的Tomcat服务器&#xff0c;但是在本机就不能访问&#xff0c;前提是在本机下可以ping的通虚拟机的IP地址的&#xff0c;最后经过Google&#xff0c;发现说可能是…

Linux下配置OpenLDAP服务记录

摘要&#xff1a;最近部门需要整合所有的系统&#xff0c;所以领导说要通过OpenLdap数据库来实现对所有系统的统一管理&#xff0c;所以需要在服务器上配置一下LDAP服务&#xff0c;我们这里选择的是OpenLdap服务&#xff0c;我在网上搜索了很多&#xff0c;开始都没有配置成功…

Linux下配置CollabNet Subversion Edge

摘要&#xff1a;最近一直都在搞一下管理员的工作&#xff0c;今天又搞了svn的管理工具CollabNetSubversionEdge&#xff0c;网上也有很多例子&#xff0c;但是很多都是可以访问到web界面&#xff0c;但是不能启动版本库的服务&#xff0c;所以我经过多次尝试&#xff0c;终于解…

养成让自己进步的10个习惯

养成让自己进步的10个习惯 1.永远不说不可能。"办法总比问题多" 2.凡事第一反应找方法&#xff0c;不是找借口。"不要推卸责任" 3.养成记录习惯&#xff0c;不太依赖脑袋。"好记性不如烂笔头" 4.每天出门照镜子&#xff0c;给自己自信的微笑。&…

Oracle存储过程中使用游标来批量解析CLOB字段里面的xml字符串:

摘要&#xff1a;之前在项目中使用到了Oracle数据库中通过触发器去调用存储过程执行数据解析并Update到对应的数据表中&#xff0c;但是&#xff0c;经过一段时间的测试使用发现&#xff0c;如果job那天停掉了&#xff0c;然后你再重新新建job的话&#xff0c;这时候可能会有很…

Maven配置nexus

摘要&#xff1a;近来一直在搭建maven结构的开发框架&#xff0c;其中这个过程中用到了nexus私服&#xff0c;这里我把我经过查询总结的最终的方式记录一下&#xff0c;以便后面忘记了&#xff1a; 一&#xff1a;nexus私服的安装(略) 二&#xff1a;仓库的讲解如下图: 1、ho…