一.指针的概念

指针是编程语言中的一个对象,利用地址,它的值直接指向存在内存中某一的值。由于通过地址能找到所需变量的存储地址,可以说地址指向它所对应的变量单元。因此,将地址被形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元
指针变量也是一个变量,指针存放的内容是一个地址,该地址指向一块内存空间

二.指针变量

指针变量是指针类型的数据,指针类型和基本类型一样,是C语言常用的数据类型之一。

2.1 指针变量的定义:

定义指针变量时要明确指针指向的数据的类型,因为不同类型的数据在内存中的长度是不同的,如:一般的计算机中int型占4个字节,char类型占1个字节,指针要明确自己指向的数据在内存中的长度,这样才能正确的对指向的数据进行操作

int *p; //表示定义一个指针变量
*p;     //代表指针所指内存的数据

指针变量只能存放地址,不能将一个int型变量直接赋值给一个指针,如,int *p = 100是错误的

2.2 指针类型的兼容性

指针变量之间赋值比普通数据类型赋值要求更为严格,例如:不可以把double *赋值给int *
相同类型的指针指向相同类型的变量地址,不能用一种类型的指针指向与其不同类型变量的地址

2.3 指针变量常用的运算符:

取地址运算符:&

取地址运算符“&”,对变量(基本类型数据)使用该运算符,可以获得变量在内存当中的地址(一个指针类型的数据)

int p1 = 1;     //定义一个int类型的变量p1
int *p = &p1;   //将p1的地址赋给p

解引用运算符:*

解引用运算符“*”,对地址(指针类型数据)使用该运算符,可以获得地址对应的内存单元中存储的数据

int p1 = 1;     //定义一个int类型的变量p1
int *p = &p1;   //将p1的地址赋给p
printf("p1的值为%d",*p);   //输出指针p指向的变量中存储的数据

三.指针的分类

3.1 无类型指针

定义一个指针变量,但不指定它指向哪种具体的数据类型,这是这个指针就是无类型指针

void *p; //使用void关键字定义了一个无类型指针

可以通过强制转化将void *无类型指针转换为其他类型的指针,也可以用(void *)强制转换将其他类型的指针强制转换为void无类型指针
void无类型指针转换为其他类型指针:

void *p;    //定义一个无类型指针
(int*)p;    //使用时将p强制转换为int类型的指针

其他类型指针转换为void无类型指针:

int *p;     //定义一个int类型指针
(void*)p;   //使用时将p强制转换为void无类型的指针

3.2 空指针

指向NULL的指针叫空指针
空指针通常在给指针初始化时使用,让声明的指针指向NULL,当使用时再给指针赋准确的值

C语言类型:NULL

NULL在C语言中的定义为( void * ) 0

3.3 野指针

没有具体指向任何变量地址的指针叫野指针
野指针是没有明确指向的指针,比如声明一个指针却没有对其初始化int * p,此时该指针的指向不明确,可能会指向系统占用的内存或其他垃圾数据,编程时应注意避免野指针的出现

3.4 指向常量的指针与指针常量

声明指针变量时使用const关键字

指向常量的指针:

const char *p;  //定义一个指向常量的指针,该指针可以指向不同的常量

指针常量:

char *const p;  //定义一个指针常量,一旦初始化之后其内容不可改变,即该指针指向一个固定的地址,该地址中的内容时可以变化的

3.5 数组指针

数组名是一个指针,即指向数组首元素的地址
若定义一个int类型的数组a[10],则a是一个int类型的指针

int a[10];
int *p = a;

“[]”也是一个运算符,其功能和“*”解引用运算符的功能相同,都可取出地址中存放的数据

3.4 多级指针

指针就是一个变量,既然是变量就也存在内存地址,所以可以定义一个指向指针的指针,即指向指针的指针(二级指针)

int i = 10;
int *p1 = &i;
int **p2 = &p1;
printf("%d\n", **p2);   //输出一个地址

指向多维数组的指针

表达式 含义
int a[3][5] 定义一个二维数组,a为数组首地址
int (*a)[5] 定义一个指向int [5]类型的指针变量a
a[0], *(a + 0), *a 0行,0列元素地址
a + 1 第1行首地址
a[1], *(a + 1) 第1行,0列元素地址
a[1] + 2, *(a + 1) + 2, & a[1][2] 第1行,2列元素地址
*(a[1] + 2), *(*(a + 1) + 2), a[1][2] 第1行,2列元素的值

3.5 函数指针

函数指针是指向函数的指针,指针可以指向变量,数组,也可以指向一个函数。
每一个函数在编译的时候会分配一个入口地址,这个入口地址就是函数指针,函数名称就代表函数的入口地址(和数组类似)。

1)函数指针的定义方式:

函数返回类型 ( * 指针变量名称 ) ( 参数列表 )

int (*p)(int);  //定义了一个指向int func(int n)类型函数的指针

2)函数指针的特点:

函数可以通过函数指针调用
使用函数指针可以实现根据条件调用不同的函数:

void man(){printf("抽烟\n");printf("喝酒\n");printf("打牌\n");
}
void woman(){printf("化妆\n");printf("逛街\n");printf("网购\n");
}
int main(){//声明一个函数指针,此时函数指针没有明确的指向void(*p)();int i = 0;scanf("%d", &i);if (i == 0)p = man;elsep = woman;//调用函数pp();return 0;
}

在回调函数和运行期动态绑定的时候大量的用到了函数指针

回调函数

回调函数就是通过函数指针调用的函数。如果把函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这个被调用的函数为回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
如下例中,max函数和add函数均为回调函数,func根据不同的情况,有选择性的调用两个函数中的一个

int max(int a, int b){if (a > b)return a;elsereturn b;
}
int add(int a, int b){return a + b;
}
void func(int(*p)(int, int), int a, int b){int res = p(a, b);printf("%d\n", res);
}
int main(){int  i = 0;scanf("%d", &i);if (i == 0)func(max, 10, 20);elsefunc(add, 10, 20);return 0;
}

四.指针运算

指针运算不是简单的整数加减法,而是以指针指向的数据类型在内存中占用字节数的倍数的运算,指针运算的实质是指针在内存中指向的移动。

char *p;
p++;        //移动sizeof(char)个字节数
int *p1;
p1++        //移动sizeof(int)个字节数
p1+4;       //p1移动4个长度单位(4*sizeof(int)的长度)

通过指针使用数组元素

指针的加减运算可以使指针移动,所以指针可以非常方便的操作数组

int a[10];
int *p = a;
p + 1;  //代表&a[1]
p + 5;  //代表&a[5]

C语言基础-01-指针相关推荐

  1. c语言指针地址交换程序,C语言-基础教程-指针的地址分配

    我们可以定义指针变量指向任何类型的变量.在上述的处理过程中,指针变量指向的变量通过传递变量的地址来实现.指针变量的取值是内存的地址,这个地址应当是安全的,不可以是随意的,否则,写入内存单元的值将会使得 ...

  2. C语言基础专题 - 指针(编写中)

    C语言基础专题 - C的灵魂没了篇 本文介绍了C语言中指针及其用法 - 由于博主水平有限,疏忽在所难免.若发现错误请告知博主更正,十分感谢. - 邮箱:291148484@163.com - 希望博文 ...

  3. C语言基础01——初识C语言

    目录 什么是C语言 第一个C语言程序:HelloWorld 初识数据类型 初识常量.变量 初始字符串.转义字符.注释 初识选择语句.循环语句 初识函数.数组 初识关键字 定义常量和宏 格式化输入输出 ...

  4. Android NDK开发之C语言基础及指针①

    我们知道 , Android系统是基于linux开发 , 采用的是linux内核 , Android APP开发大部分也要和系统打交道 , 只是Android FrameWork 帮我们屏蔽了系统操作 ...

  5. Python程序设计语言基础01:Python基本语法元素

    目录 1. 编译和解释 1.1 编译 1.2 解释 2. 程序的基本编写方法IPO 2.1 含义 2.2 输入 2.3 输出 2.4 处理 3. 使用编程解决问题 3.1 问题的计算部分 3.2 编程 ...

  6. OC语言基础 - 01

    OC语言源自于C语言,但是在C语言的基础上增加了不少OC特有的东西.因此有C语言和面向对象语言基础的同学还是可以很快掌握OC语言的. 在OC语言中,使用#import来代替C语言中的#include. ...

  7. C语言基础——字符串指针(指向字符串的指针)

    C语言中没有类似java,python等面向对象的编程语言中string那样的特定的字符串类型,通常是将字符串放在一个字符数组中. 遍历字符串代码: #include<stdio.h> # ...

  8. c语言指针 查找字符串,C语言基础及指针⑥字符操作

    字符操作 , 是我们写程序时 , 最常用的一种操作 , 例如:字符串截取 , 字符串替换 , 字符串转整数类型等等 , 都是字符操作 , 在java中String类就是二三十个方法 , 还有Strin ...

  9. C语言基础-01 基础知识

    一.C语言的特点 二.最简单的C语言程序 1.基础知识 (1)scanf: 输入,从命令行将用户输入的值,保存到变量中. int x = 0: scanf("%d" ,&x ...

  10. C语言基础10——指针进阶。字符指针、指针数组、数组指针、函数指针、函数指针数组、回调函数、数组名详解、杨氏矩阵、字符串旋转

    目录 字符指针 指针数组 数组指针 数组传参.指针参数 函数指针 函数指针数组 指向函数指针数组的指针 回调函数 练习 数组名的意义 指针笔试题 字符指针 字符指针的另一种使用方式 #include ...

最新文章

  1. 医学顶刊BMJ打脸谷歌:AI取代医生检测乳腺癌还远着呢
  2. 如何用手机打开dcm格式图片_手机也能当扫描仪用?如何用手机扫描图片?
  3. Pygame中rect 初探
  4. mysql第四篇:数据操作之多表查询
  5. java自定义findbugs规则_静态代码扫描 (三)——FindBugs 自定义规则入门
  6. 数字签名的java实现(RSA,DSA)
  7. 如何解决高并发,秒杀问题
  8. 前端学习(2832):小程序事件绑定2
  9. 985研究生连论文都不会写,还面试什么大厂
  10. python程序打包成安卓app教程_Python打包方法基本应用方式介绍
  11. linux texmaker编译,在Ubuntu下安装和编译LaTex
  12. python 遍历两个列表_python 如何在一个for循环中遍历两个列表
  13. centos6.5 安装mono
  14. python3 主函数_Python3---常见函数---if __name__ == __main__
  15. 管理感情:工作犯错了,不要狡辩,不要把错误推到别人身上
  16. 代谢组与微生物联合分析实战
  17. edius裁剪快捷键_EDIUS 快捷键大全 edius常用快捷键大全
  18. python提取国家名称缩写_如何从python中的国家缩写中获取国家名称,并混合使用alpha_2和alpha_3 ccodes...
  19. Excel批量随机生成姓名
  20. r语言实现岭回归_R语言回归篇

热门文章

  1. jack插头_防水连接器航空插头特点
  2. python统计频数_python统计单词出现次数
  3. reflexil教程_【转载】教你使用 Reflexil 反编译.NET
  4. javascript createelement_如何创建与框架无关的JavaScript插件
  5. React:AntDesign引入简介
  6. vscode 单击跳转 ctrl+鼠标左键不能跳转到函数或变量的定义
  7. 分布式存储系统学习笔记(二)—分布式文件系统(2)—淘宝文件系统(TFS)
  8. Sending form data
  9. WebSocket 实现链接 群聊(low low low 版本)
  10. python正则表达式(1)--特殊字符