【C语言】指针那些事(上)

C语言系列

文章目录


文章目录

一. 字符指针

一.(1 ) 数组创建空间的地址和指针指向的地址

二. 指针数组

二.(1)指针数组模拟一个二维数组

​         三. 数组指针

         三.(1)数组指针到底有什么用

对一维数组没有什么用

二.(2)正常的二维数组传参的写法 

总结


前言

该文章详细的讲解都有啥指针,及包括指针的日常使用等等,各位可以愉快的食用该文章的对于指针的理解,可以为大家对指针的理解加深一点。


一. 字符指针

关于指针的基本常识:
1. 指针变量就是个变量,用来存放地址,地址唯一标识一块内存空间。
理解:内存单元是有编号,编号 == 地址 == 指针 要存起来的话就需要一个指针变量 
2. 指针的大小是固定的4 / 8个字节(32位平台 / 64位平台)。
理解:地址/指针的大小是4/8个字节,或者是指针变量的大小是4/8个字节
3. 指针是有类型,指针的类型决定了指针的 + -整数的步长,指针解引用操作的时候的权限。
4. 指针的运算。

int main()
{char ch = 'w';char* pc = &ch;//将一个字符w的地址赋值给到char*类型的指针变量里面去char* p = "abcdef";//该字符串作为一个表达式的时候它的值其实是首字符的地址//当我们把这个字符串赋给p的时候,其实就是将该字符串的首地址赋给p//当我们在x86环境下,一个指针变量是4个字节//常量字符串无法被改变printf("%s\n", p);//通过这个字符指针,可以连续访问整个字符串printf("%c\n",*p);//对p进行解引用只能拿到一个字符return 0;
}

一.(1 ) 数组创建空间的地址和指针指向的地址

我们直接在代码中添加注释,以及游行图,让大家可以更加直观的理解代码中的指针的应用:

int main()
{char str1[] = "hello bit.";char str2[] = "hello bit.";//str1和str2两个数组创建了两个不同空间//系统创建一个常量字符串,因为常量字符串无法被修改,//所以系统不会创建两个相同的常量字符串,//str3和str4这两个指针变量指向的就是那个相同的常量字符串的首地址//str3和str4还是两个不同的指针变量,但是它们的存放的值是相同的const char* str3 = "hello bit.";const char* str4 = "hello bit.";if (str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if (str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return 0;
}


 二. 指针数组

关于指针数组是个啥?

指针数组是数组
字符数组 - 存放字符的数组
整型数组 - 存放整型的数组
指针数组 - 存放指针的数组,存放在数组中的元素都是指针类型的

  int*         arr[5];//存放整型指针的数组
//整型指针类型 aar数组
char* ch[6];//存放字符指针的数组

int main()
{int a = 1;int b = 2;int c = 3;int d = 4;//不会有人这样使用,因为怎样使用的话,就是多此一举,还不如直接将数字写进数字里面去int* arr[] = { &a,&b,&c,&d };return 0;
}

二.(1)指针数组模拟一个二维数组

我们直接在代码中添加注释,以及游行图,让大家可以更加直观的理解代码中的指针的应用:

int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };//int* int* int*  //因为是arr1的地址指向的是数组中的整型,所以是整形指针//这个时候就可以认为arr数组是一个指针数组int* arr[] = { arr1,arr2,arr3 };int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){printf("%d", arr[i][j]);}printf("\n");}return 0;
}

int main()
{//指针数组:就是数组类型是指针类型的数组 char* arr[5] = { "hello bit","hehe","penggeC","bitejiuyeke","c++" };int i = 0;for (i = 0; i < 5; i++){printf("%s\n", arr[i]);}return 0;
}

 三. 数组指针

啥是数组指针: 

指针数组 - 是数组,是存放指针的数组
数组指针 - 是指针
字符指针 - 指向字符的指针
整型指针 - 指向整型的指针
浮点型指针 - 指向浮点数指针
数组指针 - 指向数组的指针

将数组的地址赋给数组指针

 数组名的理解
 数组名是数组首元素的地址
 但是存在两个例外
 1,sizeof(数组名)
 2,&数组名,这里的数组名表示整个数组,取出的是数组的地址

int main()
{int arr[10];printf("%p\n", arr);//数组名是首元素的地址int*printf("%p\n", arr+1);//数组名是首元素的地址+1就是加一个整数4printf("%p\n", &arr[0]);//arr[0]是首元素地址int*printf("%p\n", &arr[0]+1);//arr[0]是首元素地址+1就是加一个整数4printf("%p\n", &arr);//arr的数组地址printf("%p\n", &arr+1);//加1就是增加了一个数组的大小//指针类型决定了指针+1.到底是+几个字节return 0;
}

三.(1)数组指针到底有什么用

对一维数组没有什么用

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr;int i = 0;for (i = 0; i < 10; i++){printf("%d", p[i]);}//int (*p)[10] = &arr//int i = 0;/*for (i = 0; i < 10;){printf("%d", (*p)[i]);}*///这两种形式上不同,但是他们的结果是相同的return 0;
}

二.(2)正常的二维数组传参的写法 

//数组名就是首元素地址 
void print(int arr[3][5], int r, int c)//数组传参同样传的首元素地址,
//首元素的地址是二维数组第一行的地址,
{int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){printf("%d ", arr[i][j]);}printf("\n");}
}
print(int (*p)[5], int r, int c)
//使用数组指针的形式,传的二维数组,但是指向的第一行的一维数组的地址,一行有5个,
//必须要写成一个一维数组的指针才可以
{int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){printf("%d ", p[i][j]);}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };print(arr, 3, 5);return 0;
}
void print(int arr[], int sz)//形式参数是数组形式,因为数组传参传的就是一个地址,而不是创建一个新的数组
{//写成数组形式的形参是因为方便新手理解int i = 0;for (i = 0; i < sz; i++){printf("%d", arr[i]);}
}
void print(int* arr, int sz)//形式参数是指针的形式
{int i = 0;for (i = 0; i < sz; i++){printf("%d", arr[i]);//arr[i] ===> *(arr+i)}
}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);print(arr, sz);//一维数组传参传的是数组名,而数组名也等于数组首元素地址return 0;
}
int arr[5];//arr是一个能够存放5个整型数组数据的数组
int* parr1[10];//parr是一个指针数组,数组大小为10个元素,类型为整型指针类型
int(*parr2)[10];//parr2是一个数组指针,该指针是指向数组的,指向的数组有10个元素,每个元素的类型的是整型
int(*parr3[10])[5];//parr3是一个数组,是存放数组指针的数组,这个数组有10个元素,存放的这个数组指针,指向的数组有5个元素,每个元素都是整型

总结

本文详细的的介绍了一部分的指针的知识,还有代码的理解帮助,并不是全部的知识,大家感觉有用处就好

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

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

相关文章

React-表单受控绑定和获取Dom元素

一、表单受控组件 1.声明一个react状态 说明&#xff1a;useState const [value,setValue]useState("") 2.核心绑定流程 2.1绑定react状态 <div><input value{value}type"text"></input> 2.2绑定onChange事件 说明&#xff1a;e.…

Java工具库——Commons IO的50个常用方法

工具库介绍 Commons IO&#xff08;Apache Commons IO&#xff09;是一个广泛用于 Java 开发的开源工具库&#xff0c;由Apache软件基金会维护和支持。这个库旨在简化文件和流操作&#xff0c;提供了各种实用工具类和方法&#xff0c;以便更轻松地进行输入输出操作。以下是 Com…

python:使用Scikit-image对遥感影像进行傅里叶变换特征提取(fourier)

作者:CSDN @ _养乐多_ 在本博客中,我们将介绍如何使用Scikit-Image来进行傅里叶变换特征提取(fourier),并且提供一个示例代码,演示了如何在单波段遥感图像上应用这些方法。 傅里叶变换特征提取是一种数学工具,用于将图像中的细节、纹理和边缘信息以不同频率的方式呈现…

关爱通分享丨三大步九小步—重构管理价值链,驱动福利进阶

企业人才素质不断提升&#xff0c;对生活品质和精神层面的追求越来越高&#xff0c;也倒推企业不断改善管理、健全福利制度&#xff0c;激发员工的积极性和创造力。企业成本激增&#xff0c;但预期价值未能完全实现&#xff0c;为此&#xff0c;笔者在价值驱动管理理念的基础上…

PostgreSQL 基础知识

执行环境&#xff1a; psql 1. 创建一个表格 CREATE TABLE customers ( customer_id serial PRIMARY KEY,firstname VARCHAR(100) NOT NULL,lastname VARCHAR(100) NOT NULL,username VARCHAR(50) UNIQUE NOT NULL,password VARCHAR(50) NOT NULL,email VARCHAR(255) UNIQUE …

FreeRTOS 中断管理介绍和实操

目录 中断定义 中断优先级 相关注意 中断相关函数 1.队列 2.信号量 3.事件标志组 4.任务通知 5.软件定时器 中断管理实操 中断定义 中断是指在程序执行的过程中&#xff0c;突然发生了某种事件&#xff0c;需要立即停止当前正在执行的程序&#xff0c;并转而处理这个…

内网穿透工具之NATAPP(一)

使用工具前&#xff0c;有必要了解一下什么是内网穿透吧&#xff01; 内网穿透简单来说就是将内网外网通过natapp隧道打通,让内网的数据让外网可以获取。比如常用的办公室软件等&#xff0c;一般在办公室或家里&#xff0c;通过拨号上网&#xff0c;这样办公软件只有在本地的局…

手写RPC框架

文章目录 什么是RPC框架RPC框架中的关键点通信协议序列化协议动态代理和反射 目前已有的RPC框架手写RPC框架介绍项目框架项目执行流程项目启动 什么是RPC框架 RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;, 简单来说遵循RPC协议的就是RPC框架. …

基于小安派AiPi-Eye-S1的Nes游戏机

1.作品展示 作品功能可见以下B站视频 外壳可以使用灰太狼大佬提供的外壳STL文件。在嘉立创三维猴上打印&#xff08;外壳12元快递6元&#xff09;。 外壳从以下的帖子中获取&#xff1a; 模型分享 2.作品说明 2.1 硬件部分 硬件上使用到了AiPi-Eye-S1开发板以及3.5寸 240*3…

rust学习——智能指针

智能指针 在各个编程语言中&#xff0c;指针的概念几乎都是相同的&#xff1a;指针是一个包含了内存地址的变量&#xff0c;该内存地址引用或者指向了另外的数据。 在 Rust 中&#xff0c;最常见的指针类型是引用&#xff0c;引用通过 & 符号表示。不同于其它语言&#xf…

【Redis】Docker部署Redis数据库

Docker部署Redis数据库 1. Redis介绍2. CentOS 7 安装 & Docker 配置3. 拉取Redis 镜像、创建容器3.1 配置Docker镜像源3.2 拉取Redis 镜像3.3 容器创建 1. Redis介绍 Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务&#xff0c;是一个开源的使用…

新一代AI技术,引领医疗智能革新共筑未来医疗生态

加快推进数字化转型&#xff0c;是我国抢抓新一轮科技革命和产业变革机遇的必然选择&#xff0c;数字化转型已不是“选择题”&#xff0c;而是关乎生存和长远发展的“必修课”。在此目标下&#xff0c;公共服务领域迎来深刻变革&#xff0c;医院也不例外&#xff0c;数字经济的…

力扣每日一题73:矩阵置零

题目描述&#xff1a; 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例 2…

MySQL 5.7限制general_log日志大小

背景 需求&#xff1a; 在MySQL 5.7.41中开启general_log 并限制其大小&#xff0c;避免快速增长占用硬盘空间。 解决&#xff1a; 通过定时任务&#xff0c;执行简单的脚本&#xff0c;判断general_log 日志的大小&#xff0c;实现对通用查询日志的“每日备份”或“每日清…

基于群居蜘蛛算法的无人机航迹规划

基于群居蜘蛛算法的无人机航迹规划 文章目录 基于群居蜘蛛算法的无人机航迹规划1.群居蜘蛛搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用群居蜘蛛算法来优化无人机航迹规划。 …

如何使用 Docker 搭建 Jenkins 环境?从安装到精通

不少兄弟搭 jenkins 环境有问题&#xff0c;有的同学用 window, 有的同学用 mac&#xff0c; 有的同学用 linux。 还有的同学公司用 window, 家里用 mac&#xff0c;搭个环境头发掉了一地。。。 这回我们用 docker 去搭建 jenkins 环境&#xff0c;不管你是用的是什么系统&…

一文5000字从0到1使用Jmeter实现轻量级的接口自动化测试(图文并茂)

接口测试虽然作为版本的一环&#xff0c;但是也是有一套完整的体系&#xff0c;有接口的功能测试、性能测试、安全测试&#xff1b;同时&#xff0c;由于接口的特性&#xff0c;接口的自动化低成本高收益的&#xff0c;使用一些开源工具或一些轻量级的方法&#xff0c;在测试用…

【PointNet—论文笔记分享】

第一个直接基于原始点云数据进行分割、分类的模型&#xff0c;之前都是基于多视图或者体素的方式。 论文: PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation代码: TensorFlow版 Pytorch版 基本模型架构&#xff1a; 分别对每个点进行特征提取…

SpringBoot集成Redis Cluster集群(附带Linux部署Redis Cluster高可用集群)

目录 一、前言二、集成配置2.1、POM2.2、添加配置文件application.yml2.3、编写配置文件2.4、编写启动类2.5、编写测试类测试是否连接成功 一、前言 这里会使用到spring-boot-starter-data-redis包&#xff0c;spring boot 2的spring-boot-starter-data-redis中&#xff0c;默…

适用于物联网的UI设计工具都有哪些?

随着科学技术的飞速发展&#xff0c;“万物相连的互联网”时代逐渐成为现实。如今&#xff0c;物联网已经不是什么新词了。事实上&#xff0c;早在各种屏幕设备诞生之前&#xff0c;人们就与物理世界交织在一起&#xff0c;产生了无数的互动。如何将人们多年积累的互动经验与物…