标准C语言(8)
指针变量用来记录地址数据,指针变量的用途就是找到另外一个变量,没有记录有效地址的指针不能用来找到其它变量,声明指针变量时必须在变量名称前写*.如果一个指针变量记录了另外一个变量的地址就可以认为它们之间存在捆绑关系,在指针变量名称前使用*操作符可以表示它所捆绑的变量
- /*
- * 指针演示
- * */
- #include <stdio.h>
- int main() {
- int num = 0, num1 = 0, num2 = 0, tmp = 0;
- int *p_num = &num, *p_num1 = &num1, *p_num2 = &num2, *p_tmp = &tmp;
- printf("请输入三个数字:");
- scanf("%d%d%d", p_num, p_num1, p_num2);
- /*if (*p_num > *p_num1) {
- *p_tmp = *p_num;
- *p_num = *p_num1;
- *p_num1 = *p_tmp;
- }
- if (*p_num > *p_num2) {
- *p_tmp = *p_num;
- *p_num = *p_num2;
- *p_num2 = *p_tmp;
- }
- if (*p_num1 > *p_num2) {
- *p_tmp = *p_num1;
- *p_num1 = *p_num2;
- *p_num2 = *p_tmp;
- }*/
- if (*p_num > *p_num1) {
- p_tmp = p_num;
- p_num = p_num1;
- p_num1 = p_tmp;
- }
- if (*p_num > *p_num2) {
- p_tmp = p_num;
- p_num = p_num2;
- p_num2 = p_tmp;
- }
- if (*p_num1 > *p_num2) {
- p_tmp = p_num1;
- p_num1 = p_num2;
- p_num2 = p_tmp;
- }
- printf("%d %d %d\n", *p_num, *p_num1, *p_num2);
- return 0;
- }
声明指针变量的时候也需要提供类型名称,它表示这个指针适合与什么类型的存储区捆绑
可以在一条语句里声明多个同类型指针,必须在每个指针变量名称前单独加*
没有记录有效地址的指针分为两类
1.空指针里面记录空地址(NULL),这个地址的数值就是0.
2.其他没有记录有效地址的指针都叫做野指针
程序里禁止出现野指针,所有指针变量必须初始化
- /*
- * 指针演示
- * */
- #include <stdio.h>
- int main() {
- int arr[] = {1, 2, 3, 4, 5}, num = 0;
- int *p_num = arr;
- for (num = 0;num <= 4;num++) {
- printf("%d ", arr[num]);
- printf("%d ", p_num[num]);
- }
- printf("\n");
- return 0;
- }
对指针变量进行初始化的时候*没有参与赋值过程,指针和变量的捆绑关系会随着程序的执行不断变化,指针可以看作是存储区的某种身份
如果指针和数组里第一个存储区捆绑就可以通过指针找到数组里的每个存储区,指针后使用下标就可以表示数组里的存储区
地址数据可以参与如下计算过程
地址 + 整数 地址 - 整数 地址 - 地址
地址加减整数n实际上加减的是n个捆绑存储区的大小.数组名称加下标可以得到下标对应存储区的地址,采用如下写法也可以表示数组里的存储区
*(arr + num)
其中arr是数组名称,num是下标,这个写法可以表示数组里下标为num的存储区,地址减地址的结果是两个地址之间包含的捆绑存储区个数
- /*
- * 地址计算规则演示
- * */
- #include <stdio.h>
- int main() {
- int arr[] = {1, 2, 3, 4, 5};
- int *p_num = arr;
- printf("arr是%p,arr + 3是%p, arr - 3是%p\n", arr, arr + 3, arr - 3);
- printf("&arr[3]是%p\n", &arr[3]);
- printf("arr[3]是%d\n", arr[3]);
- printf("*(arr + 3)是%d\n", *(arr + 3));
- printf("p_num[3]是%d\n", p_num[3]);
- printf("*(p_num + 3)是%d\n", *(p_num + 3));
- printf("&arr[3] - arr是%d\n", &arr[3] - arr);
- return 0;
- }
可以使用const关键字声明指针变量,声明指针变量的时候可以把const关键字写在指针变量名称前。这种指针不可以被赋值,但是可以通过这种指针对它的捆绑存储区进行赋值。
声明指针变量的时候可以把const关键字写在类型名称前面。这种指针本身可以被赋值,但是不可以通过这种指针对它捆绑的存储区做赋值。
- /*
- * const关键字演示
- * */
- #include <stdio.h>
- int main() {
- int num = 0;
- int * const p_num = #
- const int *p_num1 = #
- *p_num = 10;
- printf("num是%d\n", num);
- //p_num = NULL; 错误
- //*p_num1 = 100; 错误
- p_num1 = NULL;
- return 0;
- }
声明指针的时候可以使用void作为类型名称可以把这种指针叫做无类型指针.这种指针可以和任意类型的存储区捆绑,无法通过这种指针本身知道它捆绑存储区的类型,不应该在这种指针前直接加*操作符也不应该对这种指针做加减整数的计算,这种指针必须首先强制类型转换成有类型指针然后才能使用
- /*
- * 无类型指针演示
- * */
- #include <stdio.h>
- int main() {
- char ch = 'o';
- int num = 45;
- float fnum = 4.5f;
- void *p_v = NULL;
- p_v = &ch;
- printf("*(char *)p_v是%c\n", *(char *)p_v);
- p_v = #
- printf("*(int *)p_v是%d\n", *(int *)p_v);
- p_v = &fnum;
- printf("*(float *)p_v是%g\n", *(float *)p_v);
- return 0;
- }
所有跨函数使用存储区都是通过指针实现的,数组做形式参数的时候真正的形式参数其实是一个指针
- /*
- * 跨函数使用存储区演示
- * */
- #include <stdio.h>
- int *read(void) {
- static int num = 0;
- printf("请输入一个数字:");
- scanf("%d", &num);
- return #
- }
- int main() {
- int *p_num = read();
- printf("数字是%d\n", *p_num);
- return 0;
- }
声明指针形式参数的时候尽量加上const关键字,无类型指针通常作为形式参数使用
使用存储区的地址做返回值可以让调用函数使用被调用函数的存储区,这个时候被调用函数需要提供一个指针类型的存储区存放作为返回值的地址数据,不可以把非静态局部变量的地址作为返回值使用
标准C语言(8)的更多相关文章
- 关于标准C语言的预定义宏【转】
标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来. __LINE__ 当 ...
- 【部分原创】标准C语言的优先级、结合性、求值顺序、未定义行为和非确定行为浅析
零. 优先级 在C++ Primer一书中,对于运算符的优先级是这样描述的: Precedence specifies how the operands are grouped. It ...
- 标准SQL语言的用法
原文链接:http://www.ifyao.com/2015/05/18/%E6%A0%87%E5%87%86%E7%9A%84sql%E8%AF%AD%E8%A8%80%E4%BD%BF%E7%94 ...
- 关于标准C语言的预定义宏
标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来.__LINE__ 当前 ...
- UML标准建模语言与应用实例
一.基本信息 标题:UML标准建模语言与应用实例 时间:2012 出版源:科技创新导报 领域分类:UML标准建模语言 面向对象 系统分析与设计 二.研究背景 问题定义:UML建模语言用图形来表现典型的 ...
- UML(统一建模语言)是通用的可视化标准建模语言。由构造块、公共机制、构架三部分组成。
UML UML(统一建模语言)是通用的可视化标准建模语言.由构造块.公共机制.构架三部分组成. 1.构造块:包括基本的UML建模元素(类.接口.用例等).关系(关联关系.依赖关系.泛化关系.实现关系) ...
- 标准C 语言总结
***************C语言****************** --day01-- Linux是一个和Windows类似的操作系统 通常通过终端软件使用Linux操作系统 终端软件里只能使用 ...
- 标准C语言(1)
C语言程序的绝大部分内容应该记录在以.c作为扩展名的文件里,这种文件叫源文件,C语言里还包含以.h作为扩展名的文件,这种文件叫做头文件 C语言程序里可以直接使用数字和加减乘除四则运算符号(*代表乘法, ...
- 【M35】让自己习惯于标准C++语言
1.最近一些年C++语言增加的特性有: a.RTTI,namespace,bool,关键字mutable和explicit,enums,以及const static int可以直接初始化. b.扩充了 ...
- 标准C语言的输入输出流(i/o)方法详解
cppreference.com -> 标准 C I/O ->详细说明 标准 C I/O clearerr 语法: #include <stdio.h> void cleare ...
随机推荐
- charles获取抓包数据
charles获取抓包数据 第一步:确保手机和电脑处于同一个局域网之下 第二步:进入 charles 的代理设定选项(主导航栏Proxy-----Proxy Setting......)中,允许代理, ...
- 对JavaScript事件处理程序/事件监听器的设定的简单介绍
下面是一些对事件处理进行设定的方式. 指定为HTML元素的属性(事件处理程序) 指定为DOM元素的属性(事件处理程序) 通过EventTarget.addEventListener()进行指定(事件监 ...
- linux系统查看当前正在运行的服务
--查看当前服务器所有服务 service --status-all -- 查看当前所有正在运行的服务 service --status-all | grep running --查看指定服务运行状态 ...
- 【机器学习】Jackknife,Bootstraping, bagging, boosting, AdaBoosting, Rand forest 和 gradient boosting
Jackknife,Bootstraping, bagging, boosting, AdaBoosting, Rand forest 和 gradient boosting 这些术语,我经常搞混淆, ...
- 51CTO下载-html+javascript+css学习宝典
一.html知识 1. meta标签 Meta: 提供网页信息,搜索引擎使用 <meta name=“aa” content=“bbb”> <meta http-equiv=“exp ...
- SolidWorks学习笔记1
鼠标 修改缩放方向 点击工具->选项->视图,点击第一条,翻转鼠标滚轮缩放方向. 平移:Ctrl+ 中键 或者右键空白处 菜单选择平移 缩放:Shift+中键 或者右键空白处 菜单选择放大 ...
- java学习-3
输入语句Scanner的使用方法 1.导包 import java.util.Scanner 2.创建 从键盘输入:Scanner sc = new Scanner(System.in); 3.使用 ...
- Python学习教程:Pandas中第二好用的函数
从网上看到一篇好的文章是关于如何学习python数据分析的迫不及待想要分享给大家,大家也可以点链接看原博客.希望对大家的学习有帮助. 本次的Python学习教程是关于Python数据分析实战基础相关内 ...
- priority_queue member function
没有优先队列的dijkstra不算真的dijkstra 所以我又回来补常识了 <1>priority_queue::emplace <7>priority_queue::top ...
- 最大两队竞争值(暴力dfs)--牛客多校第二场
题意: 给你2n个人,两两有对立竞争值,问你分成两队最大的竞争值是多少. 思路: 直接暴力dfs,稍微有点卡,3800ms. #include<iostream> #include< ...