C语言重点突破(2)指针(二)

news2024/11/15 13:01:19

本章重点

1. 字符指针
2. 数组指针
3. 指针数组
4. 数组传参和指针传参

 

1. 字符指针

在我的前一章节,我们提到指针也有类型的区分,有整型指针,浮点型指针,下面我们讲讲字符指针

字符指针的用法通常是将一个字符变量的地址存放到该指针中去,通过对指针的解引用来对该值进行操作

int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}

 其实还有一种使用方式

int main()
{
const char* pstr = "hello bit.";//这里是把一个字符串放到pstr指针变量里了吗?
printf("%s\n", pstr);
return 0;
}

运行的结果是将整个字符串输出来,这里就会有小伙伴好奇了,字符指针也能存放字符串的地址吗? 

其实结果与我们想的大不相同,本质是把字符串 的首地址存入到了指针中。

如果原理是这样的话,我们看看下面这段代码

#include <stdio.h>
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
const char *str3 = "hello bit.";
const char *str4 = "hello bit.";
if(str1 ==str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 ==str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}

 运行结果

这是为什么呢?

这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同。

2. 数组指针

数组指针,这是一个新的概念,那么它到底是数组还是指针呢?从名字上看,它是一个指针,既然指针是用来存放地址的,那么它存放的是谁的地址呢?

我们已经熟悉:
整形指针: int * pint; 能够指向整形数据的指针。
浮点型指针: float * pf; 能够指向浮点型数据的指针

那数组指针指向的应该就是数组的地址。

那数组指针该如何定义呢?

int *p1[10];
int (*p2)[10];
//p1, p2分别是什么?

很明显,p1应该是一个指针数组,这里要涉及到操作符的优先级问题,而[]的优先级要高于*号的
而p2加了一个括号,保证*与p2相结合为一个指针,定义为指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。

数组指针的使用

讲完了定义和原理,我们来看看它是如何使用的,既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。

#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int (*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p
//但是我们一般很少这样写代码
return 0;
}

正常情况下

#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col)
{
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}

printf("\n");
}
}
void print_arr2(int (*arr)[5], int row, int col)
{
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};
print_arr1(arr, 3, 5);
//数组名arr,表示首元素的地址
//但是二维数组的首元素是二维数组的第一行
//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
//可以数组指针来接收
print_arr2(arr, 3, 5);
return 0;
}

3. 指针数组

上一章讲过,指针数组就是一个存放指针变量的数组,不同的类型可以存放不同的指针

int* arr1[10]; //整形指针的数组
char *arr2[4]; //一级字符指针的数组
char **arr3[5];//二级字符指针的数组

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);
}

其实上述的传参方式都是可行的,数组传参的本质是将数组的首元素地址传入到函数中,在函数里既可以用数组存储,也能用指针进行存储。

2.二维数组传参

二维数组的传参本质上是和一维数组一样的,但区别在于它们的首元素的类型

void test(int arr[3][5])//ok?
{}
void test(int arr[][])//ok?
{}
void test(int arr[][5])//ok?
{}

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

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;
}

 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;
}

 

 




 

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

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

相关文章

请求和响应的概述

请求&#xff1a;在浏览器地址栏输入地址&#xff0c;点击回车请求服务器&#xff0c;这个过程就是一个请求过程。 响应&#xff1a;服务器根据浏览器发送的请求&#xff0c;返回数据到浏览器在网页上进行显示&#xff0c;这个过程就称之为响应。 针对Servlet的每次请求&…

配资炒股优质平台排名:十大排名和评估!

随着互联网的发展&#xff0c;配资炒股平台已经成为了越来越多投资者的选择&#xff0c;但是市场上的配资炒股平台各不相同&#xff0c;投资者如何选择一家优质的平台呢&#xff1f;这时候&#xff0c;配资炒股优质平台排名就显得尤为重要。 配资炒股优质平台排名的作用&#…

搭载国内首个教育大模型“子曰”,有道虚拟人口语教练Hi Echo今日上线

10月11日&#xff0c;网易有道宣布&#xff0c;搭载子曰教育大模型的全球首个虚拟人口语教练 Hi Echo正式推出独立APP和微信小程序。这名一对一口语教练具备全天候多平台的陪伴能力&#xff0c;将更好地为用户提供随时随地高质量的口语练习&#xff0c;让用户彻底告别哑巴英语。…

OpenGL LUT滤镜算法解析

1. 简介 滤镜&#xff1a;一些图像处理软件针对性地提供了一些对传统滤镜效果的模拟功能&#xff0c;使图像达到一种特殊效果。滤镜通常需要同通道、图层、色阶等联合使用&#xff0c;才能使图像取得最佳艺术效果。在软件界面中也直接以“滤镜”&#xff08;Filter&#xff09…

乐优商城(二)搭建后台前端

1. 搭建后台管理前端 1.1 导入已有资源 找到已经准备好的 leyou-manage-web 压缩文件&#xff0c;这就是后台管理的前端项目 解压 leyou-manage-web 文件到项目中&#xff0c;注意与 leyou 文件同级 1.2 安装依赖 在 IDEA 中打开 leyou-manage-web 工程 2.打开 Teminal&…

LeakCanary(4)面试题系列

序、慢慢来才是最快的方法。 问题1&#xff1a;LeakCanary 支持Android 场景中的那些内存泄漏监测&#xff1f; 已销毁的 Activity 对象&#xff08;进入 DESTROYED 状态&#xff09;&#xff1b;已销毁的 Fragment 对象和 Fragment View 对象&#xff08;进入 DESTROYED 状态…

面试算法25:链表中的数字相加

题目 给定两个表示非负整数的单向链表&#xff0c;请问如何实现这两个整数的相加并且把它们的和仍然用单向链表表示&#xff1f;链表中的每个节点表示整数十进制的一位&#xff0c;并且头节点对应整数的最高位数而尾节点对应整数的个位数。例如&#xff0c;两个分别表示整数98…

css吸顶特效(elementui vue3官网)

效果如图&#xff1a;当浏览器滚轮在最上面的时候 没什么区别。当鼠标滚轮超出最上面高度时会有这种粒子感。吸顶遮盖下面内容 首先要 明确 css 基础属性 position: sticky;的用法。再了解 background-image: radial-gradient(transparent 1px, #fff 1px); background-size: …

Java 8 引进的一个新特性 Optional

Optional 是 Java 8 引进的一个新特性&#xff0c;通常用于缓解常见的空指针异常问题。 Brian Goetz &#xff08;Java语言设计架构师&#xff09;对Optional设计意图的原话如下&#xff1a; Optional is intended to provide a limited mechanism for library method return…

马蹄集matji oj赛(第十二次)

目录 元素共鸣 欧拉函数 欧拉函数2 小码哥的喜欢数 整数的逆 数的自我 阶乘的质因子 分数个数 质数率 数字游戏 元素共鸣 难度&#xff1a;黄金 0时间限制&#xff1a;1秒 巴占用内存&#xff1a;128M 遥远的大陆上存在着元素共鸣的机制。 建立一个一维坐标系&#x…

保护隐私与增强网络安全之网络代理技术

目录 前言 一、网络代理技术原理 二、网络代理技术类型 1. HTTP代理 2. SOCKS代理 3. DNS代理 4. 加密代理 5. 反向代理 三、网络代理技术应用 1. 加速网络访问速度 2. 绕过网络限制 3. 保护个人隐私 4. 节省带宽 5. 改善网络安全 四、网络代理技术优缺点 网络…

APK大小缩小65%,内存减少70%:如何优化Android App

APK大小缩小65&#xff05;&#xff0c;内存减少70&#xff05;&#xff1a;如何优化Android App 我们一直在努力为我们的Android应用程序构建MVP产品。在开发MVP产品后&#xff0c;我们发现需要进行应用程序优化以提高性能。经过分析&#xff0c;我们发现了以下可以改进的应用…

比特币有助减少腐败;微软 Copilot 每月赔 20 美元;AIGC 明年会“洗冷水澡”丨 RTE 开发者日报 Vol.64

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

AMEYA360分享:村田电子搭载了Onsemi公司IoT设备专用IC的新Bluetooth® Low Energy模块开始量产

近年来&#xff0c;所有远程监控、远程控制的用例均要求具备可无线连接的电池驱动IoT设备&#xff0c;而长寿命电池与安全的数据通信功能是其关键。为此&#xff0c;在IoT边缘设备的设计方面&#xff0c;最大的课题是要提高功率效率和安全性。 Type 2EG由于无线与内置微处理器两…

React 状态管理 - Mobx 入门(下)接入实战

目录 Mobx接入实战 Mobx构造复杂应用需要注意的 Mobx5 Or Mobx4 Mobx5 Mobx4 /package.json /src/routes/index.jsx /src/app.jsx /src/index.jsx /src/models/home/index.js /src/models/index.js /src/containers/home/index.jsx Mobx VS Redux Mobx接入实战 对…

RabbitMQ之延迟队列解读

目录 基本介绍 概述 为什么需要引进RabbitMQ延迟队列 应用场景 springboot代码实战 实战架构 工程概述 RabbitConfigDeal 配置类&#xff1a;创建队列及交换机并进行绑定 MessageService业务类&#xff1a;发送消息及接收消息 主启动类RabbitMq01Application&#xff1…

2023年中国医院信息系统发展现状及行业市场规模分析[图]

医院信息系统&#xff0c;亦称“医院管理信息系统”&#xff08;简称HIS&#xff09;&#xff0c;是指利用计算机软硬件技术、网络通信技术等现代化手段&#xff0c;对医院及其所属各部门的人流、物流、财流进行综合管理&#xff0c;对在医疗活动各阶段产生的数据进行采集储存、…

Lab 1: Unix utilities汇总

这个实验主要学习了常用的一些系统调用。 Lab 1: Unix utilities Boot xv6 (easy) git克隆&#xff0c;切换分支&#xff0c;qemu。根据要求进行操作即可。 $ git clone git://g.csail.mit.edu/xv6-labs-2020 $ cd xv6-labs-2020 $ git checkout util $ make qemusleep (ea…

分享一下花店制作微信小程序的步骤是什么

一、准备阶段 在准备阶段&#xff0c;花店需要完成以下任务&#xff1a; 注册微信公众平台账号&#xff1a;首先&#xff0c;花店需要注册一个微信公众平台账号&#xff0c;这个账号将用于创建和管理微信小程序。 确定小程序的功能和需求&#xff1a;花店需要根据自身的业务需…

RISC-V架构 | 飞凌嵌入式FET7110-C国产高性能核心板现货发售!

RISC-V凭借其完全开源免费且可自由修改的特性而备受国内厂商的追捧&#xff0c;在此背景下&#xff0c;飞凌嵌入式联合RISC-V国产处理器厂商赛昉科技(StarFive)基于昉惊鸿7110处理器共同推出FET7110-C核心板。 现在&#xff0c;飞凌嵌入式FET7110-C核心板&#xff08;商业级&a…