C语言指针详解上

1 野指针

int main01(){//野指针就是没有初始化的指针,指针的指向是随机的,不可以 操作野指针//int  a = 0;//指针p保存的地址一定是定义过的(向系统申请过的)int  *p;//野指针*p = 200;printf("%d\n",*p);system("pause");return 0;}

2 空指针

空指针的作用: 如果使用完指针将指针赋值为NULL,在使用时判断一下指针是否为NULL,就知道指针有没有被使用

int main(){int  a;//将指针的值赋值为0,0x0000000 =  NULLint  *p = NULL;//给指针p的内容赋值为0*p = 200;//err  因为p保存了0x0000的地址,这个地址是不可以使用的,非法printf("%d\n",*p);system("pause");return 0;}

3 万能指针

万能指针就是可以保存任意的地址

//万能指针int main(){//void b; 不可以定义void类型的变量,因为编译器不知道给变量分配多大的空间//但是可以定义void *类型,因为指针都是4个字节int  a = 10;short b = 10;void *p = (void *)&a;//万能指针可以保存任意的地址void  *q = (void *)&b;//printf("%d\n", *p);//err  p是void*,不知道取几个字节的大小printf("%d\n",* (int *)p);// *(  (int *)地址)system("pause");return 0;}

4 const修饰的指针变量

int main(){int  a = 10;int  b = 20;//const修饰的是 * 还是变量p,//这里修饰的是*//const int  *p = &a;//不能通过 *p,改p所指向空间的内容//*p = 100; err  因为不能通过p改p所指向空间的内容//const修饰的变量p//p保存的地址不可以修改//int  * const p = &a;//p = &b;err  p本身的值不能被更改const  int *const p = &a;//p本身的指向不能改变,不能通过*p修改p//向那块空间的内容system("pause");return 0;}

5 多级指针

定义多级指针保存数据的地址时,定义的指针的类型只需要比要保持的数据的类型多一级*

//多级指针int main(){int a = 10;//*p  int a     int *pint *p = &a;//*q  int *p   int **qint **q = &p;//如果*和&相遇,相抵消// **q == *(*q) == *(p) ==  a//**q == *(*q) == *(&a) ==  aprintf("%d\n", **q);// *k  int **q  int ***kint ***k = &q;//*符号结合,代表这个k是一个指针变量//k是一个变量//k的类型,将变量k拖黑,剩下的类型//k用来保存谁的地址  将变量k和k最近的*一起拖黑,剩下什么类型//就保存什么类型数据的地址int *******************g;int ********************f = &g;system("pause");return 0;}

6 指针结合数组

指针加1,跨过一个步长

int  *p;步长  =  sizeof(int)要得到内存的数据,就该先得到数据的地址- (地址) 得到的是地址里面的内容int main(){//int  a[10] = {1,2,3,4,5,6,7,8,9,10};int  a[10] = { 0 };//a 数组名,首元素的地址int  *p = a;//指针p保存的是首元素的地址for (int i=0;i<sizeof(a)/sizeof(a[0]);i++){//printf("%d ",a[i]);//printf("%d ", *(p+i));*(p + i) = i;}for (int i = 0; i<sizeof(a) / sizeof(a[0]); i++){printf("%d ",a[i]);//printf("%d ", *(p+i));//*(p + i) = i;}system("pause");return 0;}

7 指针运算

两指针(类型一致)相减,得到的是中间跨过多少元素

两指针相加没有意义

int main(){int  a[10] = {1,2,3,4,5,6,7,8,9,10};//sizeof(int [10])int *p = a;//int  *q = (int *)(&a + 1) - 1;int  *q = &a[9];printf("%d\n",q-p);//  p+9 ==  qprintf("%d\n",*(p+3));//两指针相加没有意义// printf("%d\n", p+q);errsystem("pause");return 0;}

8 并不是数组的专属

[]==  *()int main(){//[] == *()int  a[10] = { 1,2,3,4,5,6,7,8,9,10 };int *p = a;for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++){//printf("%d ",a[i]);//a[i] == *(a+i)//printf("%d ", *(p+i));//printf("%d ", p[i]);// p[i]  == *(p+i)printf("%d ", *(a + i));}system("pause");return 0;}int main09(){//[]是不是数组的专属//int  a[10] = { 1,2,3,4,5,6,7,8,9,10 };//  []  ==  *()//p[0]   ==  *(p+0)int a = 10;int *p = &a;p[0] = 100;//p[1] = 200;printf("a=%d\n",a);system("pause");return 0;}

9 指针数组

整型数组 是一个数组,数组的每一个元素是整型

指针数组 是一个数组,数组的每一个元素都是一个指针

int main(){int a = 10;int b = 20;int c = 30;// int *p1 = &a  int *p2 = &a  int *p2 = &a//需求:  数组中的每一个元素都是指针(地址)int *num[3] = {&a,&b,&c};//printf("%d\n",sizeof(num));&a  ==  num[0]//for(int i=0;i<sizeof(num)/sizeof(num[0]);i++)//{// printf("%d\n",*num[i]);////}//定义一个指针用来保存数组num首元素的地址// num ==  &num[0] =   &(int *)  == int **//num[0]是int *类型,要保持int  *类型的地址,需要比它多一级*int **k = num;for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++){printf("%d ",**(k+i));}system("pause");return 0;}

在这里插入图片描述

10 指针作为函数的形参

指针作为函数的形参,可以改变实参的值

void swap2(int*x, int *y){int  k = *x;*x = *y;*y = k;printf("x=%d y=%d\n", *x, *y);}int main(){int  a = 10;int b = 20;//swap(a,b);swap2(&a, &b);printf("a=%d b=%d\n", a, b);system("pause");return 0;}

在这里插入图片描述

11 数组作为函数的形参

//数组作为函数的形参会退化为指针//void print_arr(int b[10]) // int  *b//void print_arr(int b[1000])//int  *bvoid print_arr(int *b,int  len){int  n = sizeof(b) / sizeof(b[0]);  // *(b+0)  == *bprintf("n=%d\n",n);for (int i = 0; i <len; i++){printf("%d ",b[i]);}printf("\n");}int main(){int  a[10] = { 1,2,3,4,5,6,7,8,9,10 };print_arr(a,sizeof(a)/sizeof(a[0]));//打印数值的内容//  &a[0]   int *system("pause");return 0;}

12 指针作为函数的返回值

int num = 0;//在函数外面定义的变量叫全局变量,整个工程都可以使用//整个变量程序启动开辟空间,直到程序结束释放空间int * getnum(){//{}中定义的变量叫局部变量,局部变量在函数结束之后的空间会被释放srand(time(NULL));num = rand();return &num;//}int main(){int * p = getnum();printf("%d\n",*p);system("pause");return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/205390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux C语言 40-进程间通信IPC之消息队列

Linux C语言 40-进程间通信IPC之消息队列 本节关键字&#xff1a;C语言 System V IPC 进程间通信 消息队列 相关库函数&#xff1a;ftok、msgget、msgsnd、msgrcv、msgctl 什么是消息队列&#xff1f; 消息队列是System V中的一种进程间通信机制&#xff08;如管道、信号量、…

手把手将Visual Studio Code变成Python开发神器

Visual Studio Code 是一款功能强大、可扩展且轻量级的代码编辑器&#xff0c;经过多年的发展&#xff0c;已经成为 Python 社区的首选代码编辑器之一 下面我们将学习如何安装 Visual Studio Code 并将其设置为 Python 开发工具&#xff0c;以及如何使用 VS Code 提高编程工作…

在 Windows 桌面的redis中远程连接到 VMware 中运行的 Linux 上的 Redis

先修改一下docker容器中的redis(一会连上之后看效果) 我使用的是VMware的虚拟机 选择的网络设置为桥接模式 查到虚拟机独立的ip是如下 允许 Linux 虚拟机上的 Redis 监听外部连接&#xff1a; 打开 Linux 虚拟机上的 Redis 配置文件。在大多数系统上&#xff0c;配置文件位于…

编程应用实例,养生馆会员管理系统软件统计查询教程

一、前言 编程应用实例&#xff0c;养生馆会员管理系统软件&#xff0c; 导航栏菜单有 系统设置&#xff1a;可以设置操作员的权限以及打印机参数设置。 会员信息登记&#xff1a;可以直接用手机号登记电子会员卡 会员卡充值&#xff1a;可以直接报手机号充值&#xff0c;…

【Java 基础】24 日期操作

文章目录 1.Date2.LocalDate3.LocalTime4.LocalDateTime5.DateTimeFormatter6.Period7.Duration8.ZoneId9.ZonedDateTime总结 日期和时间是我们常见的操作对象&#xff0c;Java 也提供了强大的日期和时间处理类库&#xff0c;使我们可以方便的进行日期的表示、计算、格式化等。…

springboot(ssm甘肃旅游工艺品商城 旅游管理系统Java(codeLW)

springboot(ssm甘肃旅游工艺品商城 旅游管理系统Java(code&LW) 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.0&…

AntDB数据库助力中国移动结算中心建设

结算中心负责中国移动漫游伙伴进行数据和财务清算支撑。本次结算中心项目涉及结算处理、资料管理、信息管理等模块&#xff0c;用以构建系统的结算能力。 建设需求 结算中心现有传统集中式架构的数据库无法做到根据业务量变化进行弹性扩缩容&#xff0c;目前系统数据量巨大&a…

ESP32-Web-Server编程- 在 Web 上开发动态纪念册

ESP32-Web-Server编程- 在 Web 上开发动态纪念册 概述 Web 有很多有趣的玩法&#xff0c;在打开网页的同时送她一个惊喜。 需求及功能解析 本节演示在 ESP32 上部署一个 Web&#xff0c;当打开对应的网页时&#xff0c;将运行动态的网页内容&#xff0c;显示炫酷的纪念贺词…

如何解决依赖传递引起的版本冲突?

依赖传递引起的版本冲突通常是由于在开发过程中&#xff0c;不同模块之间的依赖版本不匹配造成的。解决这种冲突的方法主要包括以下几种&#xff1a; 版本管理&#xff1a;在项目的配置文件中&#xff08;如 Maven 的 pom.xml 或 Gradle 的 build.gradle&#xff09;清晰地定义…

计算机操作系统4

1.什么是进程同步 2.什么是进程互斥 3.进程互斥的实现方法(软件) 4.进程互斥的实现方法(硬件) 5.遵循原则 6.总结&#xff1a; 线程是一个基本的cpu执行单元&#xff0c;也是程序执行流的最小单位。 调度算法&#xff1a;先来先服务FCFS、短作业优先、高响应比优先、时间片…

YOLOv6 学习笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、YOLOv6贡献和改进二、YOLOv6核心概念三、YOLOv6架构改进四、YOLOv6重参思想五、YOLOv6的损失函数总结 前言 在计算机视觉领域&#xff0c;目标检测技术一直…

有趣的代码——有故事背景的程序设计5

接着上篇文章再和大家分享一下有趣的代码&#xff01; 目录 1.求母串中子串的个数 2.行走机器人 3.荷兰国旗问题 4.统计考研成绩 1.求母串中子串的个数 给定一个母串s和一个子串t&#xff0c;在主串s中寻找子串t的过程为字符串匹配。每匹配成功一次&#xff0c;即母串中含有…

移动app测试要不要做第三方软件测试?

移动app测试是指通过对移动应用进行全面的评估和验证&#xff0c;以确保其功能和性能符合设计要求&#xff0c;以提供给用户最好的体验。通常包括功能测试、界面测试、性能测试、兼容性测试等多个环节。由于现在越来越多的软件企业会选择将测试工作交由第三方软件测试进行&…

【Git】本地代码如何托管到远程仓库(保姆级教程)

注意前提是你本地已经安装了Git 1. 新建远程仓库 选一个git服务器&#xff0c;新建一个远程仓库&#xff0c;这里我选用的是gitee 点击确定后&#xff0c;显示如下界面表示仓库已经新建完成 2.建立本地仓库 本地新建一个空文件夹&#xff0c;在里面写一些你的初始代码文件。…

夜莺专业版网络设备功能介绍

网络设备采集简介 网络设备的问题通常会产生较大范围的影响&#xff0c;因此采集监控网络设备是一项常见的任务。不同公司在实施网络设备采集时可能采用不同的方案&#xff0c;主要有三类&#xff1a; SNMP&#xff08;Simple Network Management Protocol&#xff09;&#x…

2个月拿下信息系统项目管理师攻略(攻略超级全)

信息系统项目管理师&#xff08;高项&#xff09;一次性过啦&#xff01;结合这次备考经验&#xff0c;给大家总结一下复习方法。 先上图&#xff0c;开心一下&#xff01; 一、我为什么选择了高项 为什么我会选信息系统项目管理师&#xff0c;也就是我们常说的高项。 原因1…

深入浅出分析kafka客户端程序设计 ----- 生产者篇----万字总结

前面在深入理解kafka中提到的只是理论上的设计原理&#xff0c; 本篇讲得是基于c语言的kafka库的程序编写&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 首先要编写生产者的代码&#xff0c;得先知道生产者的逻辑在代码上是怎么体现的 1.kafka生产者的逻辑 …

zookeeper集群 +kafka集群

1.zookeeper kafka3.0之前依赖于zookeeper zookeeper是一个开源&#xff0c;分布式的架构&#xff0c;提供协调服务&#xff08;Apache项目&#xff09; 基于观察者模式涉及的分布式服务管理架构 存储和管理数据&#xff0c;分布式节点上的服务接受观察者的注册&#xff0c…

Date与LocalDate互转

1、Date转LocalDate Date toDay new Date(); LocalDate localDate toDay.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();2、LocalDate转Date LocalDate localDate LocalDate.parse("2023-01-01", DateTimeFormatter.ISO_LOCAL_DATE); Date date D…

ubuntu18.04 vscode 安装 vue.volar Vue Language Features (Volar) , vue3 必备插件

直接在vscode 里面下载老是失败&#xff0c;不是网络问题&#xff0c;而是vue.volar插件配置的vscode版本与vscode版本不一致导致出现安装失败 官网下载最新的 vue.volar插件 https://marketplace.visualstudio.com/ 官网搜索 vue.volar 然后打开 Vue Language Features (Vol…