标准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 ...
随机推荐
- Web19_事务
MySQL的事务控制: 开启事务:start transaction; 提交:commit(); 回滚:rollback(); JDBC事务控制: 开启事务:setAutoCommit(false); ...
- 利用netsh命令设置IP地址/DNS服务器地址
一.设置IP地址 1. 自动获取IP地址: netsh interface ip set address [name=]"本地连接" [source=]dhcp 2. 手动设置IP ...
- Mac上解决Chrome浏览器跨域问题
最近做前端开发总是遇到一个很奇怪的现象,同一个AJAX请求,在Chrome里调试的时候就会提示跨域,但是在手机模拟器或者真机上调试的时候就不会,于是百度了一下,发现是Chrome的安全策略导致的,需要 ...
- 从内存上看python的对象
python中有一个说法:一切皆是对象,怎么理解这句话呢?我们可以通过查看数字,字符串在内存中的表示形式来对这句话有个更深的认识. 那么,怎么查看对象在内存中是什么样的呢?可以先参考一些这篇文章:ht ...
- pytorch中的激励函数(详细版)
初学神经网络和pytorch,这里参考大佬资料来总结一下有哪些激活函数和损失函数(pytorch表示) 首先pytorch初始化: import torch import t ...
- 使用URLOS 五分钟安装rTorrent (轻量级优秀BT/PT客户端)
rTorrent是一个非常简洁.优秀.非常轻量的BT客户端,它使用ncurses库以C++编写,将 rTorrent 用在安装有 GNU Screen 和 Secure Shell 的低端系统上作为远 ...
- IIS配置相关问题:Framework 4.5 在IIS 7.5中运行
<system.webServer> <validation validateIntegratedModeConfiguration="false" /&g ...
- Sink - 汇聚点
!!!1.Logger Sink 记录INFO级别的日志,通常用于调试. 属性说明: !channel – !type – The component type name, needs to ...
- python 爬虫 基于requests模块的get请求
需求:爬取搜狗首页的页面数据 import requests # 1.指定url url = 'https://www.sogou.com/' # 2.发起get请求:get方法会返回请求成功的响应对 ...
- SqlServer中union 和 union all的区别
⒈UNION和UNION ALL关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同.⒉对重复结果的处理:UNION在进行表链接后会筛选掉重复的数据,UNION ALL不会去除重复的 ...