C语言基础:初识指针(二)

当你不知道指针变量初始化什么时,可以初始化为空指针

int *p=NULL;

我们看NULL的定义,可以看出NULL是0被强制转化为Void* 类型的0;实质还是个0; 

如何避免野指针:
1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放即使置 NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性

 指针运算

  • 指针+- 整数
  • 指针-指针
  • 指针的关系运算

 指针+- 整数

下面这段代码实现的是打印数组的元素。

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);int* p = arr;for (i = 0; i < sz; i++){printf("%d ", *p);p = p + 1;}return 0;
}
指针 - 指针
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("%d\n", & arr[9] - &arr[0]);return 0;
}

指针-指针得到的是中间元素的个数

例如:求字符串的长度。模拟实现strlen这个函数 

int my_strlen(char* str)
{char* start = str;char* end = str;while (*end != '\0'){end++;}return end - start;
}
int main()
{char arr[] = "bit";int len = my_strlen(arr);printf("%d\n", len);return 0;
}

 指针与数组

数组名是首元素地址,怎么证明呢?通过下面的代码进行证明

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };printf("%p\n", arr);printf("%p\n", &arr[0]);return 0;
}

注意:两个例外

1.&arr   -   &数组名   -     数组名不是首元素地址-数组名表示整个数组 ,所以&数组名取出的是整个数组的地址,

2.sizeof(arr)  -  sizeof(数组名)-数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小。单位字节

下面的代码我们来看看他们的区别

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };printf("%p\n", arr);printf("%p\n", arr+1);printf("%p\n", &arr[0]);printf("%p\n", &arr[0]+1);printf("%p\n", &arr);printf("%p\n", &arr + 1);return 0;
}

调试代码如下: 

前面两个都是地址加4,最后一个加了40,(16进制的运算) 

可以看出&arr是整个数组的地址,整个数组的地址加1,是跳过(整型)4*10(元素个数)=40

既然可以把数组名当成地址存放到一个指针中,我们使用指针来访问其中任意一个就成为可能。

看下面的代码:

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,0 };int* p = arr; //指针存放数组首元素的地址int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i < sz; i++){printf("&arr[%d] = %p   <====> p+%d = %p\n", i, &arr[i], i, p + i);}return 0;
}

 可以看出是是一一对应的关系,所以 p+i 其实计算的是数组 arr 下标为i的地址。 那我们就可以直接通过指针来访问数组。

打印数组元素

int main()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };int* p = arr; //指针存放数组首元素的地址int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i < sz; i++){printf("%d ", *(p + i));}for (i = 0; i < sz; i++){printf("%d \n", arr[i]);}return 0;
}

二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?

所以我们就有二级指针

a 的类型是int 

pa 的类型是int*

ppa  的类型是int**  最后一个*表示是指针,指向的对象是int*

int main()
{int a = 10;int* pa = &a;int** ppa = &pa;printf("%d\n", **ppa);
}

指针数组

与数组指针的区别       就像好孩子,重点是孩子,

指针数组-数组   --存放指针的数组。

数组指针-指针。

为啥要与指针数组,跟数组的由来一样,看下面的代码,对同一类型的地址存储,如果一个一个写下去,太麻烦了,所以我们要有指针数组来存放,这样就方便多了。

int main()
{int a = 10;int b = 20;int c = 30;int* pa = &a;int* pb = &b;int* pc = &c;return 0;
}

 

怎么初始化呢?

int arr[10];
int* arr1[3];//指针数组初始化

存放的类型都是int* 的类型

int* arr1[3] = { &a,&b,&c };
int main()
{int a = 10;int b = 20;int c = 30;int* arr2[3] = { &a,&b,&c };int i = 0;for (i = 0; i < 3; i++){printf("%d \n", *(arr2[i]));}return 0;
}

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

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

相关文章

2024五一杯ABC题资料合集+代码+参考论文!!!

一.赛题思路 (赛题出来以后第一时间在群内分享) 二.比赛日期和时间 比赛开始时间:2024年5月1日(周三)10;00 比赛结束时间:2024年5月4日(周六&#xff09;12:00 三.将在明天分享的资料合集如下 4.我们这边会分享22年的题目完整全部的过程 5.数学建模的29个通用模型及MATLAB…

Python网络数据抓取(3):Beautiful Soup

Beautiful Soup 这个库通常被称为Beautiful Soup 4&#xff08;BS4&#xff09;。它主要用来从HTML或XML文件中抓取数据。此外&#xff0c;它也用于查询和修改HTML或XML文档中的数据。 现在&#xff0c;让我们来了解如何使用Beautiful Soup 4。我们将采用上一节中使用的HTML数据…

使用PaddlePaddle和Ernie模型来计算文本数据的向量表示

import paddle 2from paddlenlp.transformers import ErnieTokenizer, ErnieModel 3import numpy as np 4import json 5 6# 设置PaddlePaddle的全局随机种子 7paddle.seed(1234) 8 9# 初始化分词器 10tokenizer ErnieTokenizer.from_pretrained(ernie-3.0-tiny-medium-v2-zh) …

实验室温湿度设备巡检的意义

温湿度监控设备的正常运行对于实验室的科研工作来说至关重要&#xff0c;然而&#xff0c;我们常常会遇到设备出现故障或者探头不灵敏的情况&#xff0c;这给实验室的工作带来了诸多困扰&#xff0c;为了解决这些问题&#xff0c;对实验室温湿度设备进行巡检管理也是一种非常有…

前端vue如何生成二维码

有时候有需要链接直接生成二维码在手机上看的需求&#xff0c;比如下载&#xff0c;比如信息&#xff0c;比如excel 下面先引入包 import QRCode from qrcode; 然后上代码 // 将res转换成二维码const qrCodeData JSON.stringify(res); // 将res转换为字符串作为二维码数据// …

数据结构 -- 双向链表

谁说我没有死过? 出生以前, 太阳已无数次起落. 悠久的时光被悠久的虚无吞没, 又以我生日的名义卷土重来. --史铁生 目录 1. 前言2. 双向链表的结构3. 双向链表的实现4. 完整代码5. 总结 正文开始 1. 前言 双向链表是一种常见的数据结构&#xff0c;它与单向链表相比&#x…

Java+playwright+testNG实现UI自动化测试

今天来讲讲使用Java结合最新的playwright来做UI自动化测试 目前网上大部分都是关于使用Python做自动化的教程&#xff0c;Java的比较少一些&#xff0c;但是我认为使用Java做自动化还是有优点的&#xff0c;性能就好一点&#xff0c;当然大家根据实际需求来。 一、 普通UI测试 …

【python】去除水印的几种方式

1、python调用FFMEPG的delogo函数去除水印 要使用Python调用FFmpeg的delogo filter去除视频水印&#xff0c;你需要使用subprocess模块运行FFmpeg命令。以下是一个简单的Python脚本示例&#xff1a; import subprocessdef remove_watermark(input_video, output_video, logo_…

MacPro(M1,M2芯片)Java开发和常用工具开源软件合集

目录 Java开发软件1 IDE1.1 idea1.2 Vs Code 2 开发工具2.1 数据库数据库模型管理数据库连接客户端 2.2 SSH/Telnet/Serial/Shell/Sftp客户端2.3 MarkDown编辑器2.3 代码片段管理粘贴 3小工具3.1 截图贴图3.2 Mac下修改hosts文件的图形化界面软件 Java开发软件 1 IDE 1.1 ide…

如果把软路由的网段更换成169.254.0.0/16会咋样?

前言 这几天有小伙伴在折腾软路由系统&#xff0c;然后问题就来了。 他咨询的是&#xff1a;为啥电脑连接软路由之后&#xff0c;无法访问软路由的管理页&#xff1f; 嗯。。。确实不是什么大事。但不注意看&#xff0c;还以为软路由没有正常获取到ip。 熟悉网络的小伙伴们都…

教程推荐:手机应用自动化

手机应用程序的自动化通常涉及使用专门设计的自动化框架和工具。对于Android和iOS平台&#xff0c;以下是一些常用的自动化工具&#xff1a; Android: Espresso: Espresso是谷歌官方支持的自动化测试框架。它适用于写UI测试来模拟用户对Android应用的交云。Espresso工作在应用…

Python中的map()和filter()函数:深入解析与使用场景

Python中的map()和filter()函数&#xff1a;深入解析与使用场景 在Python编程中&#xff0c;map()和filter()是两个非常实用的内置函数&#xff0c;它们可以帮助我们更高效地处理数据。这两个函数都是高阶函数&#xff0c;可以接受一个函数作为参数&#xff0c;并应用于序列&a…

实例解释:溢出和进位是咋回事?不能胡来吧!

有学生给我一段程序&#xff0c;就在运行中标志位的“怪异”表现提出问题。   程序不难懂&#xff1a; assume cs:codesg codesg segment start:mov al,0fchadd al,05h ;结果不溢出mov al,0f5hadd al,87h ;结果溢出mov ax,4c00hint 21h codesg ends end start难懂的是&a…

设计模式- 访问者模式(Visitor Pattern)结构|原理|优缺点|场景|示例

设计模式&#xff08;分类&#xff09; 设计模式&#xff08;六大原则&#xff09; 创建型&#xff08;5种&#xff09; 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式 结构型&#xff08;7种&#xff09; 适配器…

leetcode-有效括号序列-94

题目要求 思路 1.使用栈的先进后出的思路&#xff0c;存储前括号&#xff0c;如果st中有对应的后括号与之匹配就说明没问题 2.有两个特殊情况就是字符串第一个就是后括号&#xff0c;这个情况本身就是不匹配的&#xff0c;还有一种是前面的n个字符串本身是匹配的&#xff0c;这…

Python中format的常见用法

一、填充 1、按默认顺序填充 name "Alice" age 25 print("My name is {} and I am {} years old.".format(name, age))输出&#xff1a;My name is Alice and I am 25 years old. 2、指定位置 name "Bob" age 30 print("My name is…

与Apollo共创生态:我们携手远航

目录 小程一言会议记录 回望7年发展展望未来小程有感 小程一言 4月22日&#xff0c;百度Apollo在北京车展前夕举办了以“破晓•拥抱智变时刻”为主题的智能汽车产品发布会。我在观看后也是很是触动 作为在校大学生的我&#xff0c;从大一开始知道Apollo开始&#xff0c;Apollo…

2024.04.09 校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招&实习 | 佑驾创新Minieye 春招补录实习&#xff08;内推&#xff09; 校招&实习 | 佑驾创新Minieye 春招补录实习&#xff08;内推&#xff09; 2、校招 | 上海复旦微电子…

STM32中I2C通信的完整C语言代码范例

在嵌入式系统开发中&#xff0c;STM32芯片是一种广泛应用的微控制器&#xff0c;具有强大的性能和丰富的外设功能。其中&#xff0c;I2C&#xff08;Inter-Integrated Circuit&#xff09;是一种常用的串行通信协议&#xff0c;用于在微控制器之间或者微控制器与外设之间进行数…

高并发实现高效内存管理

高并发下传统方式的弊端 void *malloc(size_t size);在内存的动态存储区中分配一块长度为size字节的连续区域返回该区域的首地址. void *calloc(size_t nmemb, size_t size);与malloc相似&#xff0c;参数size为申请地址的单位元素长度&#xff0c;nmemb为元素个数&#xff0…