当前位置: 首页 > 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 …...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...