什么是指针:

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

为什么使用指针

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

学习笔记11-C语言-指针相关推荐

  1. 【学习笔记】C++语言程序设计(郑莉):数组、指针与字符串

    [学习笔记]C++语言程序设计(郑莉):数组.指针与字符串 1. 数组 1.1 数组的声明与使用 1.2 数组的存储与初始化 1.3 数组作为函数参数 1.4 对象数组 2. 指针 2.1 内存空间的 ...

  2. golang学习笔记之--Go语言内建容器

    话接上文 <golang学习笔记之--Go语言基本语法> 今天继续记录学习笔记,今天的笔记主题是Go语言内建容器 如果各位童鞋想要获得下面的源码,请搜索gzh:隔壁王小猿,关注后回复&qu ...

  3. 23 DesignPatterns学习笔记:C++语言实现 --- 2.2 Adapter

    23 DesignPatterns学习笔记:C++语言实现 --- 2.2 Adapter 2016-07-22 (www.cnblogs.com/icmzn) 模式理解 1. Adapter 定义 ...

  4. Java快速入门学习笔记8 | Java语言中的数组

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  5. 23 DesignPatterns学习笔记:C++语言实现 --- 1.2 AbstractFactory

    23 DesignPatterns学习笔记:C++语言实现 --- 1.2 AbstractFactory 2016-07-21 (www.cnblogs.com/icmzn) 模式理解   1. F ...

  6. 【学习笔记】C++语言程序设计(郑莉):多态性

    [学习笔记]C++语言程序设计(郑莉):多态性 1. 多态性 2. 运算符重载 2.1 运算符重载的规则 2.2 运算符重载为成员函数 2.3 运算符重载为非成员函数 3. 虚函数 3.1 一般虚函数 ...

  7. 游戏开发学习笔记——lua脚本语言——安装、汉化与小测试(解决lua运行代码乱码问题)

    游戏开发学习笔记--lua脚本语言--安装.汉化与小测试 FOR THE SIGMA FOR THE GTINDER FOR THE ROBOMASTER 简介: Lua 是一种轻量小巧的脚本语言,用 ...

  8. 【学习笔记】C++语言程序设计(郑莉):数据的共享与保护

    [学习笔记]C++语言程序设计(郑莉):数据的共享与保护 1. 标识符的作用域与可见性 1.1 作用域 1.1.1 函数原型作用域 1.1.2 局部作用域 1.1.3 类作用域 1.1.4 命名空间作 ...

  9. 【学习笔记】C++语言程序设计(郑莉):继承与派生

    [学习笔记]C++语言程序设计(郑莉):继承与派生 1. 类的继承与派生 1.1 派生类的定义 1.2 派生类生成过程 2. 访问控制 3. 类型兼容规则 4. 派生类的构造和析构函数 4.1 构造函 ...

  10. Python学习笔记11:函数修饰符

    Python学习笔记11:函数修饰符 Python有很多有趣的特性,其中函数修饰符就是一个. 我们在之前的那个web应用示例中用过如下写法: @web.route('/log') @符号后边的,就是一 ...

最新文章

  1. 一个把ListString转化为以,隔开的字符串的方法
  2. mybatis 操作动态表+动态字段+存储过程
  3. 有关JNLP中传SESSIONID为参数的问题
  4. 192.168.8.1手机登陆_荣耀Magic UI 3.1即将升级!这10款荣耀手机4月可期
  5. 机器人码垛手持式编程_三分钟告诉你企业为什么要使用全自动码垛机械手!
  6. html5实现圆圈里带一个三角形,CSS制作箭头图标代码(圆,三角形,椭圆)c
  7. android选择多个文件_一分钟合并多个Excel、PDF文件,3种方法任你选择,好用到没朋友...
  8. System.ComponentModel.Component : MarshalByRefObject, IComponent, IDisposable
  9. river mongodb mysql_mongodb与mysql的应用场景?
  10. 2017.5.7 换教室 思考记录
  11. echarts画图实例讲解
  12. 异序二分查找 二分查找方程根 二分查找重复元素最后一个
  13. keil5写c语言的步骤,keil5使用C51的详细步骤讲述
  14. 回归中的相关系数以及R平方值和Python应用举例
  15. 正弦电压有效值推导过程(为什么与频率无关)
  16. 极限中0除以常数_第七讲 极限存在准则和两个重要极限
  17. 这个冬季,你抑郁吗?
  18. 熔断机制什么意思_熔断机制是什么意思 股市熔断是什么意思
  19. 支付宝小程序沙箱支付提示(系统繁忙,请稍后再试)
  20. 汽车灯具、连接器IPX9K IP69K防护等级测试

热门文章

  1. python源码剖析_Python源码剖析 - 对象初探
  2. python dataframe删除重复行_详解pandas使用drop_duplicates去除DataFrame重复项参数
  3. sigprocmask 阻塞进程
  4. C++中std::tr1::function和bind 组件的使用
  5. 实例解析linux内核I2C体系结构(2)
  6. 客户机和服务器在s7通信中各有什么作用,哪些通信口可以进行 Modbus TCP 通讯,作为 Modbus 服务器的 SIMATIC S7 CPU 可以...
  7. android unzip file,Unzip File in Android Assets
  8. bitnamigitlab_Bitnami Gitlab 修改端口
  9. 【转】DICOM医学图像处理:DIMSE消息发送与接收“大同小异”之DCMTK fo-dicom mDCM
  10. 【转】3.1(译)构建Async同步基元,Part 1 AsyncManualResetEvent