C语言基础-01-指针
一.指针的概念
指针是编程语言中的一个对象,利用地址,它的值直接指向存在内存中某一的值。由于通过地址能找到所需变量的存储地址,可以说地址指向它所对应的变量单元。因此,将地址被形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元
指针变量也是一个变量,指针存放的内容是一个地址,该地址指向一块内存空间
二.指针变量
指针变量是指针类型的数据,指针类型和基本类型一样,是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-指针相关推荐
- c语言指针地址交换程序,C语言-基础教程-指针的地址分配
我们可以定义指针变量指向任何类型的变量.在上述的处理过程中,指针变量指向的变量通过传递变量的地址来实现.指针变量的取值是内存的地址,这个地址应当是安全的,不可以是随意的,否则,写入内存单元的值将会使得 ...
- C语言基础专题 - 指针(编写中)
C语言基础专题 - C的灵魂没了篇 本文介绍了C语言中指针及其用法 - 由于博主水平有限,疏忽在所难免.若发现错误请告知博主更正,十分感谢. - 邮箱:291148484@163.com - 希望博文 ...
- C语言基础01——初识C语言
目录 什么是C语言 第一个C语言程序:HelloWorld 初识数据类型 初识常量.变量 初始字符串.转义字符.注释 初识选择语句.循环语句 初识函数.数组 初识关键字 定义常量和宏 格式化输入输出 ...
- Android NDK开发之C语言基础及指针①
我们知道 , Android系统是基于linux开发 , 采用的是linux内核 , Android APP开发大部分也要和系统打交道 , 只是Android FrameWork 帮我们屏蔽了系统操作 ...
- Python程序设计语言基础01:Python基本语法元素
目录 1. 编译和解释 1.1 编译 1.2 解释 2. 程序的基本编写方法IPO 2.1 含义 2.2 输入 2.3 输出 2.4 处理 3. 使用编程解决问题 3.1 问题的计算部分 3.2 编程 ...
- OC语言基础 - 01
OC语言源自于C语言,但是在C语言的基础上增加了不少OC特有的东西.因此有C语言和面向对象语言基础的同学还是可以很快掌握OC语言的. 在OC语言中,使用#import来代替C语言中的#include. ...
- C语言基础——字符串指针(指向字符串的指针)
C语言中没有类似java,python等面向对象的编程语言中string那样的特定的字符串类型,通常是将字符串放在一个字符数组中. 遍历字符串代码: #include<stdio.h> # ...
- c语言指针 查找字符串,C语言基础及指针⑥字符操作
字符操作 , 是我们写程序时 , 最常用的一种操作 , 例如:字符串截取 , 字符串替换 , 字符串转整数类型等等 , 都是字符操作 , 在java中String类就是二三十个方法 , 还有Strin ...
- C语言基础-01 基础知识
一.C语言的特点 二.最简单的C语言程序 1.基础知识 (1)scanf: 输入,从命令行将用户输入的值,保存到变量中. int x = 0: scanf("%d" ,&x ...
- C语言基础10——指针进阶。字符指针、指针数组、数组指针、函数指针、函数指针数组、回调函数、数组名详解、杨氏矩阵、字符串旋转
目录 字符指针 指针数组 数组指针 数组传参.指针参数 函数指针 函数指针数组 指向函数指针数组的指针 回调函数 练习 数组名的意义 指针笔试题 字符指针 字符指针的另一种使用方式 #include ...
最新文章
- 医学顶刊BMJ打脸谷歌:AI取代医生检测乳腺癌还远着呢
- 如何用手机打开dcm格式图片_手机也能当扫描仪用?如何用手机扫描图片?
- Pygame中rect 初探
- mysql第四篇:数据操作之多表查询
- java自定义findbugs规则_静态代码扫描 (三)——FindBugs 自定义规则入门
- 数字签名的java实现(RSA,DSA)
- 如何解决高并发,秒杀问题
- 前端学习(2832):小程序事件绑定2
- 985研究生连论文都不会写,还面试什么大厂
- python程序打包成安卓app教程_Python打包方法基本应用方式介绍
- linux texmaker编译,在Ubuntu下安装和编译LaTex
- python 遍历两个列表_python 如何在一个for循环中遍历两个列表
- centos6.5 安装mono
- python3 主函数_Python3---常见函数---if __name__ == __main__
- 管理感情:工作犯错了,不要狡辩,不要把错误推到别人身上
- 代谢组与微生物联合分析实战
- edius裁剪快捷键_EDIUS 快捷键大全 edius常用快捷键大全
- python提取国家名称缩写_如何从python中的国家缩写中获取国家名称,并混合使用alpha_2和alpha_3 ccodes...
- Excel批量随机生成姓名
- r语言实现岭回归_R语言回归篇
热门文章
- jack插头_防水连接器航空插头特点
- python统计频数_python统计单词出现次数
- reflexil教程_【转载】教你使用 Reflexil 反编译.NET
- javascript createelement_如何创建与框架无关的JavaScript插件
- React:AntDesign引入简介
- vscode 单击跳转 ctrl+鼠标左键不能跳转到函数或变量的定义
- 分布式存储系统学习笔记(二)—分布式文件系统(2)—淘宝文件系统(TFS)
- Sending form data
- WebSocket 实现链接 群聊(low low low 版本)
- python正则表达式(1)--特殊字符