C进阶(2/7)前篇——指针进阶

前言:本文章讲解部分指针进阶内容。后续继续更新。

文章重点:

1. 字符指针

2. 数组指针

3. 指针数组

4. 数组传参和指针传参

目录

前言:本文章讲解部分指针进阶内容。后续继续更新。

指针初阶了解:

1.字符指针

1.1一道有关于字符指针的面试题:

2.指针数组

2.1指针数组使用方法

 3.数组指针

3.1回顾下对数组名的理解:

3.2数组指针的定义

3.3数组指针的使用

4.数组参数、指针参数

4.1一维数组传参

4.2二维数组传参

 4.3一级指针传参

4.4二级指针传参


指针初阶了解:

1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。

2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。

3. 指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限。

4. 指针的运算。

正文正式开始

1.字符指针

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

将字符或者字符串首个地址放入指针变量中:

int main()
{char ch = 'w';char* pc = &ch;char* p = "abcdef";//p存放的是字符串首个字符的地址,类似于数组printf("%s\n","abc");printf("%s\n","abcdef");printf("%c\n","abcdef"[3]);//“abcdef”相当于数组名已知了首地址便可以根据下标打印字符printf("%c\n",*p);//可知道p存放的是字符“abcdef”的首字符地址printf("%s\n",p);//得到字符串首字符地址便可将字符全部打印出来return 0;
}

 注意:“abcdef”是常量字符串,而常量字符串是不能被修改的,所以不能通过指针解引用来修改字符串内容。强行更改会导致程序崩溃。

 为此我们可以在代码中加入const限制修改指针指向的内容:

int main()
{const char* p = "abcdef";*p = 'e';printf("%c", *p);return 0;
}

容易让我们以为是把字符串  hello  放到字符指针 pstr 里了,但是/本质是把字符串 hello  首字符的地址放到了pstr中。

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

1.1一道有关于字符指针的面试题:

代码给出可以自己在编译器运行试验

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

 1.首先知数组str1和数组str2存放的都是数组的地址,但是编译器为两个数组在内存中分别开辟了两个空间来存放数组元素,因此他们数组首元素的地址必然是不相同的。

2.对于str3和str4来说“hello bit.”是一个常量字符串。无法被修改,因此无需保存多份相同内容,因此str3和str4指针变量存放的是同一个常量字符串的地址。但是他们仍然是两个独立的指针变量只是存放的值是相同的。

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

2.指针数组

在初始学习指针时我们也学了指针数组,指针数组是一个存放指针的数组

int* arr1[10]; //存放整形指针的数组
char *arr2[4]; //存放字符指针的数组
char **arr3[5];//二级字符指针的数组//存放在数组中的元素都是指针类型的

2.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 *数据 arr1 arr2 arr3int* 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", "xiaotiancai", "woyao当大佬", "C++" };int i = 0;for (i = 0; i < 5; i++){printf("%s\n", arr[i]);}return 0;
}

 3.数组指针

3.1回顾下对数组名的理解:

数组名是数组首元素的地址
但是存在2个例外:
1. sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节
2. &数组名,这里的数组名表示整个数组,取出的是数组的地址

int main()
{int arr[10];printf("%p\n", arr);//int*printf("%p\n", arr+1);printf("%p\n", &arr[0]);//int*printf("%p\n", &arr[0] + 1);printf("%p\n", &arr);//printf("%p\n", &arr+1);//指针类型决定了指针+1,到底+几个字节return 0;
}

总结:根据上面的代码我们发现,其实&arr和arr,虽然值是一样的,但是意义是不一样的。 实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型 数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.

3.2数组指针的定义

数组指针是指针?还是数组?

答案是:指针。 

  • 整形指针: int * ps; 能够指向整形数据的指针。
  • 浮点型指针: float * pr; 能够指向浮点型数据的指针。
  • 那数组指针应该是:能够指向数组的指针。
int *p1[10];  //指针数组int (*p2)[10];//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个
指针,指向一个数组,叫数组指针。//这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。

3.3数组指针的使用

数组指针指向的是数组,那数组指针中存放的应该是数组的地址。

#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j;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++){int j;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,其实相当于第一行的地址,是一维数组的地址//可以数组指针来接收printf("\n");print_arr2(arr, 3, 5);return 0;
}

 我们来看看下面的代码分别是什么意思:

int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];
  1. arr是一个整型数组能存放五个整型数据。
  2. parr1是一个整型指针数组能够存放十个int *类型元素。
  3. parr2是一个数组指针,该指针指向的是一个数组,数组里有十个元素,每个元素是int。
  4. parr3是一个数组,是存放数组指针的数组。

4.数组参数、指针参数

在写代码的时候难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计呢?

4.1一维数组传参

 以上一维数组传参都是正确的。

4.2二维数组传参

 4.3一级指针传参

 一级指针传参,一级指针接收

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

void test(int* p)
{;
}//可以传递的有:int a=10;int *ptr=&a;int arr[5];test(arr);//可以传一维数组数组名test(&a);//可以传变量的地址test(ptr);//可以传整型指针

4.4二级指针传参

二级指针传参,二级指针接收

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

void test(char **p)
{;
}int main()
{char c = 'b';char*pc = &c;char**ppc = &pc;char* arr[10];test(&pc);//可以传一个一级指针变量的地址test(ppc);//可以传一个二级指针变量test(arr);//可以传一个数组二级指针地址return 0;
}


 今天的内容到此结束,下一节将继续更新C指针进阶内容。感谢大佬们的支持。

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

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

相关文章

大模型基础:GPT家族与提示学习

大模型基础:GPT 家族与提示学习 从 GPT-1 到 GPT-3.5 GPT(Generative Pre-trained Transformer)是 Google 于2018年提出的一种基于 Transformer 的预训练语言模型。它标志着自然语言处理领域从 RNN 时代进入 Transformer 时代。GPT 的发展历史和技术特点如下: GPT-12018年6月…

java面试基础 -- 方法重载 方法重写

目录 重载 重写 重载 方法的重载是指在同一个类中定义多个方法, 他们具有相同的名称, 但是具有不同的参数列表, 例如: public void myMethod(int arg1) {// 方法体 }public void myMethod(int arg1, int arg2) {// 方法体 }public void myMethod(String arg1) {// 方法体 }…

软硬件免费,服务收费:网络安全商业模式正在被颠覆

大数据产业创新服务媒体 ——聚焦数据 改变商业 从元宇宙到造汽车&#xff0c;重回国内A股市场五年的360一路苦追热点。一直到大模型横空出世&#xff0c;360才算真正找到感觉&#xff0c;经历一次战略上的回归。 在8月9日的互联网安全大会上&#xff0c;一袭红衣的红衣教主周…

财务数据分析之现金流量表模板分享

现金流量表是我们常说的财务数据分析三表之一。它可以呈现一个企业的现金流情况&#xff0c;揭示企业经营管理健康状态&#xff0c;但在实际使用中却有总给人一种用不上、用不好的矛盾感。怎么才能把现金流量表做好&#xff1f;不如借鉴下大神的现金流量表模板。 下面介绍的是…

Docker 本地镜像发布到私有仓库

1. 本地镜像发布到私有库流程 2. 是什么 1 官方Docker Hub地址&#xff1a;https://hub.docker.com/&#xff0c;中国大陆访问太慢了且准备被阿里云取代的趋势&#xff0c;不太主流。 2 Dockerhub、阿里云这样的公共镜像仓库可能不太方便&#xff0c;涉及机密的公司不可能提供镜…

基于Gradio的GPT聊天程序

网上很多别人写的&#xff0c;要用账号也不放心。就自己写了一个基于gradio的聊天界面&#xff0c;部署后可以本地运行。 特点&#xff1a; 可以用openai的&#xff0c;也可以用api2d&#xff0c;其他api可以自己测试一下。使用了langchain的库 可以更改模型&#xff0c;会的…

使用插件实现pdf,word预览功能

效果 代码&#xff1a; 插件地址&#xff1a; https://github.com/501351981/vue-office <a-modalv-model:visible"visible":title"title"ok"handleOk":bodyStyle"bodyStyle":width"1200":maskClosable"false"…

MySQL卸载并重装指定版本

MySQL卸载并重装制定版本 学习新的项目&#xff0c;发现之前的Navicat已经失去了与现有MySQL的链接&#xff0c;而且版本也不适合&#xff0c;为了少走弯路&#xff0c;准备直接重装相应版本的MySQL 卸载现有MySQL 停止windows的MySQL服务&#xff0c;【windowsR】打开运行框…

【ChatGPT 指令大全】怎么使用ChatGPT来辅助知识学习

目录 概念解说 简易教学 深度教学 教学与测验 解释一个主题的背后原理 总结 在当今信息时代&#xff0c;互联网的快速发展为我们获取知识提供了前所未有的便利。而其中&#xff0c;人工智能技术的应用也为我们的学习和交流带来了新的可能性。作为一种基于自然语言处理的人…

2023年国赛数学建模思路 - 复盘:校园消费行为分析

文章目录 0 赛题思路1 赛题背景2 分析目标3 数据说明4 数据预处理5 数据分析5.1 食堂就餐行为分析5.2 学生消费行为分析 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 赛题背景 校园一卡通是集…

HDFS原理剖析

一、概述 HDFS是Hadoop的分布式文件系统&#xff08;Hadoop Distributed File System&#xff09;&#xff0c;实现大规模数据可靠的分布式读写。HDFS针对的使用场景是数据读写具有“一次写&#xff0c;多次读”的特征&#xff0c;而数据“写”操作是顺序写&#xff0c;也就是…

maven install

maven install maven 的 install 命令&#xff0c;当我们的一个 maven 模块想要依赖其他目录下的模块时&#xff0c;直接添加会找不到对应的模块&#xff0c;只需要找到需要引入的模块&#xff0c;执行 install 命令&#xff0c;就会将该模块放入本地仓库&#xff0c;就可以进…

机器学习基础之《分类算法(1)—sklearn转换器和估计器》

一、转换器 1、什么是转换器 之前做特征工程的步骤&#xff1a; &#xff08;1&#xff09;第一步就是实例化了一个转换器类&#xff08;Transformer&#xff09; &#xff08;2&#xff09;第二步就是调用fit_transform&#xff0c;进行数据的转换 2、我们把特征工程的接口称…

EthGlobal 巴黎站 Chainlink 获奖项目介绍

在 Web3 中&#xff0c;每一周都至关重要。项目的发布、版本的发布以及协议的更新以惊人的速度推出。开发者必须保持学习&#xff0c;随时了解最新的工具&#xff0c;并将所有他们所学的东西&#xff08;无论是旧的还是新的&#xff09;联系起来&#xff0c;以构建推动 Web3 技…

时序预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元时间序列预测

时序预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元时间序列预测 目录 时序预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 时序预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积…

首发 | FOSS分布式全闪对象存储系统白皮书

一、 产品概述 1. 当前存储的挑战 随着云计算、物联网、5G、大数据、人工智能等新技术的飞速发展&#xff0c;数据呈现爆发式增长&#xff0c;预计到2025年中国数据量将增长到48.6ZB&#xff0c;超过80%为非结构化数据。 同时&#xff0c;数字经济正在成为我国经济发展的新…

2023年国赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…

OpenCV实例(八)车牌字符识别技术(二)字符识别

车牌字符识别技术&#xff08;二&#xff09;字符识别 1.字符识别原理及其发展阶段2.字符识别方法3.英文、数字识别4.车牌定位实例 1.字符识别原理及其发展阶段 匹配判别是字符识别的基本思想&#xff0c;与其他模式识别的应用非常类似。字符识别的基本原理就是对字符图像进行…

【佳佳怪文献分享】MVFusion: 利用语义对齐的多视角 3D 物体检测雷达和相机融合

标题&#xff1a;MVFusion: Multi-View 3D Object Detection with Semantic-aligned Radar and Camera Fusion 作者&#xff1a;Zizhang Wu , Guilian Chen , Yuanzhu Gan , Lei Wang , Jian Pu 来源&#xff1a;2023 IEEE International Conference on Robotics and Automat…

【Mariadb高可用MHA】

目录 一、概述 1.概念 2.组成 3.特点 4.工作原理 二、案例介绍 1.192.168.42.3 2.192.168.42.4 3.192.168.42.5 4.192.168.42.6 三、实际构建MHA 1.ssh免密登录 1.1 所有节点配置hosts 1.2 192.168.42.3 1.3 192.168.42.4 1.4 192.168.42.5 1.5 192.168.42.6 …