标准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 ...
随机推荐
- 2019.12.05【ABAP随笔】 分组循环(LOOP AT Group) / REDUCE
ABAP 7.40新语法 LOOP AT Group 和 REDUCE *LOOP AT itab result [cond] GROUP BY key ( key1 = dobj1 key2 = d ...
- 安装好oracle11gR2之后在相应路径下却没有生成tnsnames.ora和listener.ora
oracle安装帖子:https://blog.csdn.net/wjb123sw99/article/details/80780277 oracle安装过程中检查失败:需开启C盘共享,或者勾选忽略, ...
- C#与Unity 数据存储
使用Json存储数据 1.创建Json文件,直接创建txt文件,将后缀名改为xx.json 2.Json文件的数据格式,中括号表示列表,即中括号下的每个逗号隔开的内容都是列表的每个元素,花括号表示对象 ...
- PJzhang:U盘容量变小后的恢复以及U盘加密
猫宁!!! 参考链接:https://jingyan.baidu.com/article/8ebacdf0544ae049f65cd5da.html 我的一个U盘,16G,制作了deepin linu ...
- webdriervAPI(元素等待)
from selenium import webdriver from selenium.common.exceptions import NoSuchElementException driv ...
- 【神经网络与深度学习】gflags介绍
gflags是什么: gflags是google的一个开源的处理命令行参数的库,使用c++开发,具备python接口,可以替代getopt. gflags使用起来比getopt方便,但是不支持参数的简 ...
- docker-compose 部署elk+解决时间不对导致kibana找不到logstash定义的index + docker-compose安装
1.拉代码 git clone https://github.com/deviantony/docker-elk.git 2.docker-compose配置文件 [root@host7 docker ...
- 【有奖征集】报表模板库邀您提反馈,轻松赢取P30!
>>立即参赛 赛事初衷 大数据时代,数据的价值愈发彰显,什么样的报表才能真正帮助业务决策?这几乎是所有信息化建设的企业和个人都在思考的问题. 作为报表领域标杆企业,葡萄城于2017年推出了 ...
- Linux下安装双JDK环境与双服务器
安装双JDK环境和双服务器,具体操作如下: (1)使用tar -xvf命令解压Tomcat: (2)在Tomcat服务器下的bin文件夹下的catalina.sh文件中的头部加入以下内容: (3)修改 ...
- ETL初探
初识ETL 概念 ETL即Extract-Transform-Load.目的是将分散.凌乱.异质的数据整合在一起,为决策提供分析数据,是BI项目(Business Intellifence)项目中重要 ...