当前位置: 首页 > news >正文

进阶C语言-指针的进阶(上)

在这里插入图片描述

指针的进阶

  • 📖1.字符指针
  • 📖2.指针数组
  • 📖3.数组指针
    • 🎈3.1 数组指针的定义
    • 🎈3.2 &数组名VS数组名
    • 🎈3.3 数组指针的使用
  • 📖4.数组参数、指针参数
    • 🎈4.1一维数组传参
    • 🎈4.2二维数组传参
    • 🎈4.3一级指针传参
    • 🎈4.4二级指针传参

通过前面的学习,我们了解了指针的概念:

  1. 指针变量就是一个变量,用来存放地址,地址唯一标识一块内存空间。
  2. 指针的大小是固定为4/8个字节(32位平台/64位平台)。
  3. 指针是有类型的,指针的类型决定了指针的±整数的步长,指针解引用操作的时候的权限。
  4. 指针的运算。

📖1.字符指针

🔭在指针的类型中我们知道有一种指针类型为字符指针 char*

#include <stdio.h>
int main()
{char ch = 'w';char* pc = &ch;const char* p = "abcdef";//这里不是将字符串全部赋给p,而是将字符串首字符的地址赋给pprintf("%s\n", p);//相当于char arr[] = "abcdef";return 0;
}

在这里插入图片描述
🎈下面,我们来看一道题:

#include <stdio.h>
int main()
{char str1[] = "hello world.";char str2[] = "hello world.";const char* str3 = "hello world.";const char* str4 = "hello world.";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;
}

📖图解:
在这里插入图片描述
✅运行结果:

在这里插入图片描述

📖2.指针数组

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

//可以使用指针数组模拟一个二维数组
#include <stdio.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };int* arr[] = { arr1,arr2,arr3 };//            int * int * int *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;
}

在这里插入图片描述

//指针数组存放多个字符串:
#include <stdio.h>
int main()
{char* arr[5] = { "hello world","nihao","hehe","C","C++" };int i = 0;for (i = 0; i < 5; i++){printf("%s\n", arr[i]);}return 0;
}

在这里插入图片描述

📖3.数组指针

🎈3.1 数组指针的定义

数组指针是指针还是数组?
🏆答案是指针
字符指针-指向字符的指针。
整型指针-指向整型的指针。
浮点型指针-指向浮点型的指针。
那么数组指针就是指向数组的指针。

🎈3.2 &数组名VS数组名

//对数组名的理解
//数组名是数组首元素的地址
//但存在两个例外:
//1.sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节。
//2.&数组名,这里的数组名表示整个数组,取出的是数组的地址。
#include <stdio.h>
int main()
{int arr[10];printf("%p\n", arr);//int *printf("%p\n", arr+1);printf("%p\n", &arr);printf("%p\n", &arr+1);printf("%p\n", &arr[0]);//int *printf("%p\n", &arr[0]+1);return 0;
}

在这里插入图片描述
❗这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。

#include <stdio.h>
int main()
{int arr[10] = { 0 };int(*p)[10] = &arr;//p是用来存放数组的指针,是数组指针char* arr2[5];char* (*pc)[5] = &arr2;int arr3[] = { 1,2,3 };int(*pv)[3] = &arr3;//[]中不能为空return 0;
}

🎈3.3 数组指针的使用

🔭关于一维数组:

#include <stdio.h>
void print(int* arr, int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", 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;
}

在这里插入图片描述

#include <stdio.h>
void print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", 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;
}

在这里插入图片描述
🔭关于二维数组(数组指针更多的应用于二维数组):

#include <stdio.h>
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");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5 },{ 6, 7, 8, 9, 10},{3,4,5,6,7} };print(arr, 3, 5);//arr是二维数组的数组名,是首元素的地址,是第一行元素的地址return 0;
}

在这里插入图片描述

#include <stdio.h>
void print(int (*p)[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 ", p[i][j]);}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5 },{ 6, 7, 8, 9, 10},{3,4,5,6,7} };print(arr, 3, 5);return 0;
}

在这里插入图片描述
📝学了指针数组和数组指针我们来一起回顾并看看下面代码的意思:

int arr[5];//arr是一个能够存放5个整型数据的数组
int *parr1[10];//parr1是一个数组,数组有10个元素,每个元素的类型是int*
int (*parr2)[10];//parr2是一个指针,该指针是指向数值的,指向的数组有10个元素,每个元素的类型是int
int (*parr3[10])[5];//parr3是一个数组,是存放数组指针的数组,这个数组有10个元素,存放的这个数组指针指向的数组有5个元素,每个元素是int类型。

📖4.数组参数、指针参数

🎈4.1一维数组传参

#include <stdio.h>
void test(int arr[])//ok数组传参,形参可以写成数组的形式
//数组传参的本质就是传递了数组首元素的地址
{}
void test(int arr[10])//ok
{}
void test(int *arr)//ok数组传参,形式也可以是指针
{}
void test2(int *arr[20])//ok
{}
void test2(int **arr)//ok
{}
int main()
{
int arr[10] = {0};
int *arr2[20] = {0};
test(arr);
test2(arr2);
}

🎈4.2二维数组传参

void test(int arr[3][5])//ok
{}
void test(int arr[][])//不可以省略第二个[]里的数字
{}
//行可以省略,列不能省略
void test(int arr[][5])//ok
{}
//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
//这样才方便运算。
void test(int *arr)//不行
{}
void test(int* arr[5])//不行
{}
void test(int (*arr)[5])//ok
{}
void test(int **arr)//不行
{}
int main()
{
int arr[3][5] = {0};
test(arr);
}

🎈4.3一级指针传参

#include <stdio.h>
//一级指针传参,形参部分写成一级指针就可以了
void print(int *p, int sz)
{
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d\n", *(p+i));
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9};
int *p = arr;
int sz = sizeof(arr)/sizeof(arr[0]);
//一级指针p,传给函数
print(p, sz);
return 0;
}

🔭当一个函数的参数部分为一级指针的时候,函数能接受什么参数?

#include <stdio.h>
void test(int* p)
{
}
int main()
{int a = 0;int* ptr = &a;int arr[5];test(arr);//传整型一维数组的数组名test(&a);//传整型变量的地址test(ptr);//传整型指针return 0;
}

🎈4.4二级指针传参

#include <stdio.h>
void test(int** ptr)
{
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0;
}

🔭当函数的参数为二级指针的时候,可以接收什么参数:

void test(char **p)
{ }
int main()
{
char c = 'b';
char*pc = &c;
char**ppc = &pc;
char* arr[10];
test(&pc);
test(ppc);
test(arr);//Ok
return 0;
}

好啦,关于进阶指针(上)的知识点到这里就结束啦,后期会继续更新C语言的相关知识,欢迎大家持续关注、点赞和评论!❤️❤️❤️

相关文章:

进阶C语言-指针的进阶(上)

指针的进阶 &#x1f4d6;1.字符指针&#x1f4d6;2.指针数组&#x1f4d6;3.数组指针&#x1f388;3.1 数组指针的定义&#x1f388;3.2 &数组名VS数组名&#x1f388;3.3 数组指针的使用 &#x1f4d6;4.数组参数、指针参数&#x1f388;4.1一维数组传参&#x1f388;4.2…...

初始化一个 vite + vue 项目

创建项目 首先使用以下命令创建一个vite项目 npm create vite然后根据提示命令 cd 到刚创建的项目目录下&#xff0c;使用npm install安装所需要的依赖包&#xff0c;再使用npm run dev即可启动项目 配置 vite.config.js 添加process.env配置&#xff0c;如果下面 vue-route…...

关于B+树

在数据库管理系统中&#xff0c;使用b树作为索引的数据结构&#xff0c;相比于B树和二叉树&#xff0c;有以下几个好处&#xff1a; b树的非叶子节点只存储关键字和指针&#xff0c;不存储数据&#xff0c;这样可以增加每个节点的关键字数量&#xff0c;降低树的高度&#xff…...

axios 请求和响应拦截器

1. 创建实例 使用 axios.create() 使用自定义配置创建一个 axios 实例。 const $http axios.create({timeout: 1000,headers: {Content-Type: application/json,} })2. 拦截器 在请求或响应被 then 或者 catch 处理前拦截他们&#xff0c;拦截分为请求拦截和响应拦截。 //…...

Element-ui select远程搜索

template部分: <el-form-item label"用户" prop"userId"><el-selectv-model"temp.userId"placeholder"用户"filterableremote:reserve-keyword"false":remote-method"remoteMethod":loading"loadi…...

【Express.js】Docker部署

Docker部署 本节我们来介绍如何使用 Docker 部署 express 应用 准备工作 linux 系统安装好 Docker一个基础的 evp-express-cli 项目&#xff0c;选上 pkg 工具包Docker 的详细用法本文不做介绍&#xff0c;请先自行查阅了解 在 Docker 中部署源码 一个很简单的部署方法就是…...

面试2:通用能力

15丨如何做好开场&#xff1a;给自我介绍加“特效 第一层&#xff0c;满足面试官对信息的期待 这是对自我介绍的基本要求&#xff0c;把个人信息、主要经历、经验和技能有条理地组织起来&#xff0c; 有逻辑地讲出来。需要找出多段经历的关联性和发展变化&#xff0c;形成连…...

zookeeper/HA集群配置

1.zookeep配置 1.1 安装4台虚拟机 &#xff08;1&#xff09;按照如下设置准备四台虚拟机&#xff0c;其中三台作为zookeeper&#xff0c;配置每台机器相应的IP&#xff0c;hostname&#xff0c;下载vim&#xff0c;ntpdate配置定时器定时更新时间&#xff0c;psmisc&#xff…...

4.6版本Wordpress漏洞复现

文章目录 一、搭建环境二、漏洞复现1.抓包2.准备payload3.发送payload4.检查是否上传成功5.连接payload 国外的&#xff1a;Wordpress&#xff0c;Drupal&#xff0c;Joomla&#xff0c;这是国外最流行的3大CMS。国内则是DedeCMS和帝国&#xff0c;PHPCMS等。 国内的CMS会追求大…...

腾讯云学生专属便宜云服务器如何购买?

随着云计算技术的快速发展&#xff0c;越来越多的学生开始关注和使用云服务器。腾讯云作为国内知名的云计算服务提供商&#xff0c;推出了一系列针对学生的优惠活动&#xff0c;让更多学生能够享受到云服务器的便利和优势。本文将详细介绍如何购买腾讯云学生专属的便宜云服务器…...

逗号分隔String字符串 - 数组 - 集合,相互转换

1. 准备一个逗号分割字符串 String str "小张,小王,小李,小赵";2. 逗号分割字符串转换为集合(转换为集合之前会先转换为数组) // 第一种&#xff1a;先用split将字符串按逗号分割为数组&#xff0c;再用Arrays.asList将数组转换为集合 List<String> strList…...

基于blockqueue的生产和消费模型

线程篇下讲的是基于阻塞队列的生产者消费者模型。在学习这个之前我们先了解一些其他概念&#xff1a; 同步&#xff1a;在保证数据安全的条件下&#xff0c;让线程按某种特定的顺序依次访问临界资源。 通过上一节的代码我们实现了一个多线程抢票的程序&#xff0c;但结果显示…...

Editors(Vim)

文章目录 Editors(Vim)学哪一个编辑器&#xff1f;Vim Philosophy of VimModal editing 模态编辑Basics 基础知识Inserting text 插入文本Buffers, tabs, and windows 缓冲区、选项卡和窗口Command-line 命令行 Vim’s interface is a programming language. Vim的接口是一种编…...

【Leetcode】134.加油站

一、题目 1、题目描述 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 给定两个整数数组 gas 和 cost,如果你…...

设计模式-建造者(生成器)模式

文章目录 简介建造者模式的核心概念产品&#xff08;Product&#xff09;建造者&#xff08;Builder&#xff09;指挥者&#xff08;Director&#xff09;建造者模式与其他设计模式的关系工厂模式和建造者模式uml对比 建造者模式的实现步骤建造者模式的应用场景spring中应用 建…...

内存泄露排查思路

1、泄露情况 启动闪退运行一段时间宕机 2、排查步骤 获取堆内存快照dump使用VisualVM分析dump文件通过查看堆信息的情况&#xff0c;定位内存溢出问题 jmap -dump:formatb,fileheap.hprof pid -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath输出路径 3、在VisualVM中分…...

kafka学习-概念与简单实战

目录 1、核心概念 消息和批次 Topic和Partition Replicas Offset broker和集群 生产者和消费者 2、开发实战 2.1、消息发送 介绍 代码实现 2.2、消息消费 介绍 代码实现 2.3、SpringBoot Kafka pom application.yaml KafkaConfig producer consumer 1、核心…...

爬虫进阶-反爬破解5(selenium的优势和点击操作+chrome的远程调试能力+通过Chrome隔离实现一台电脑登陆多个账号)

目录 一、selenium的优势和点击操作 二、chrome的远程调试能力 三、通过Chrome隔离实现一台电脑登陆多个账号 一、selenium的优势和点击操作 1.环境搭建 工具&#xff1a;Chrome浏览器chromedriverselenium win用户&#xff1a;chromedriver.exe放在python.exe旁边 MacO…...

音视频编码格式-AAC ADT

例子:config 1408 1408(16进制) : 0001 0100 0000 1000 audioObjectType&#xff08;5bit&#xff09;为 00010 , 即 2&#xff0c; profie (audioObjectType -1 ) AAC LC samplingFrequencyIndex (4bit) 为 1000 , 即 8 , 对应的采样频率为 16000 channelConfiguration (…...

【计算机网络】网络编程接口 Socket API 解读(3)

Socket 是网络协议栈暴露给编程人员的 API&#xff0c;相比复杂的计算机网络协议&#xff0c;API 对关键操作和配置数据进行了抽象&#xff0c;简化了程序编程。 本文讲述的 socket 内容源自 Linux 发行版 centos 9 上的 man 工具&#xff0c;和其他平台&#xff08;比如 os-x …...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...