深入理解指针:【探索指针的高级概念和应用一】

news2024/9/23 5:27:18

目录

前言:

1. 字符指针

2. 指针数组

3.数组指针

3.1数组指针的定义

3.2 &数组名VS数组名

3.3数组指针的使用


前言:

🍂在了解今天的内容之前我们先复习一下指针的基本概念:

1,内存单元是有编号的,编号就是我们所说的地址,也可以叫指针,它们是一回事。如果我们把一个指针或地址存起来的话,我们就需要一个指针变量

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

3,地址或指针的大小是固定的4/8个字节(32位平台/64位平台),也可以理解为指针变量的大小是4/8个字节。

4,指针是有类型的,指针的类型决定了指针加减整数的步长,指针解引用操作时候的权限。


1. 字符指针

在指针的类型中我们知道有一种指针类型为字符指针 char* :
🍂一般使用:

#include <stdio.h>

int main()
{
	char ch = 'w';

	//取出的变量ch的地址是char类型的变量,
	//就可以把它放在char* 类型的指针里边去
	char* pc = &ch;

	return 0;
}

🍂还有一种使用方式如下:

#include <stdio.h>

int main()
{
	//这个字符串作为一个表达式的时候它的值是首字符的地址,指向字符串的本质是指向了第一个字符,
	//但因为字符串在内存中是连续存放的,也可以认为是指向了一个字符串
	//加const是为了防止有人通过*p修改字符串常量里边的内容
	const char* p = "abcdef";
	printf("%s\n", p);

	//如果对这个指针解引用,因为它是char*类型,解引用只拿到一个字符,所以格式控制符应该用“%c”
	printf("%c\n", *p);

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

🍂这里最终输出的是: 

🎈分析: 

 如上图所示,st1数组和str2数组是两块独立的空间,它们的起始地址肯定不相同,所以打印的结果为不同;“hello bit”是一个常量字符串,它不能被修改,而对于常量字符串来说,它的内容一样的时候,只会保存一份,不会保存多份,当这个字符串把首字符的地址交给str3的时候,str3就是一个指针变量,里边存的是'h'的地址,同理,str4指针变量里边存放的也是'h'的地址,所以,str3和str4打印结果相同。


2. 指针数组

在刚接触指针的时候我们就说过指针数组是数组。那该怎么理解它呢?

🎈我们说:

字符数组是存放字符的数组;

整型数组是存放整形的数组;

那指针数组就是存放指针的数组,即存放在数组中的元素都是指针类型的。

🎈例:

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

 🍂下面我们使用指针数组模拟一个二维数组:

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

 🍇运行结果:


3.数组指针

3.1数组指针的定义

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

答案是指针。

  • 我们知道字符指针是指向字符的指针;
  • 整形指针是指向整形的指针;
  • 浮点型指针是指向浮点型的指针;
  • 那数组指针就是指向数组的指针!

3.2 &数组名VS数组名

🎈对于下面的数组:

int arr[10];

arr 和 &arr 分别是啥?我们知道arr是数组名,数组名表示数组首元素的地址。那&arr数组名到底是啥?我们看一段代码:

#include <stdio.h>

int main()
{
	int arr[10];

	printf("%p\n", arr);
	printf("%p\n", &arr);

	return 0;
}

🍂运行结果如下: 

可见数组名和&数组名打印的地址是一样的,难道两个是一样的吗?我们再看一段代码:

#include <stdio.h>

int main()
{
	int arr[10] = { 0 };

	printf("arr = %p\n", arr);
	printf("arr+1 = %p\n", arr + 1);

	printf("&arr= %p\n", &arr);
	printf("&arr+1= %p\n", &arr + 1);

	return 0;
}

🍂运行结果如下: 

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

3.3数组指针的使用

 那数组指针是怎么使用的呢?

既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址,看代码:

#include <stdio.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	int(*p)[10] = &arr;//把数组arr的地址赋给数组指针变量p
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		//因为p里边存放的是&arr,对它解引用,
		//就相当于拿到了数组名(取地址和解引用可以互相抵消),
		//这时候访问数组里边每个元素的时候还得用下标(*p)[i],就会显得多此一举
		//所以我们一般很少这样写代码
		(*p) == (*&arr) == (arr);
	}

	//正确写法
	int* p = arr;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", p[i]);
	}

	return 0;
}

🍂数组指针的使用: 

#include <stdio.h>

void print_arr1(int arr[3][5], int x, int y)//形参也是使用二维数组的形式
{
	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");
	}
}

void print_arr2(int (*arr)[5], int x, int y)//形参的部分使用的是指针
{
	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}, {2,3,4,5,6},{3,4,5,6,7} };
	print_arr1(arr, 3, 5);//二维数组传参

	//数组名arr,表示首元素的地址
	//但是二维数组的首元素是二维数组的第一行
	//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
	//可以数组指针来接收
	print_arr2(arr, 3, 5);//二维数组传参
	return 0;
}


 


🍂下面我们再来分析一组代码:

int arr[5];

arr是一个数组,数组有5个元素,每个元素是整形类型,所以arr是一个能够存放5个整形数据的数组 

int* parr1[10];

parr1是一个数组,数组有10个元素,每个元素的类型是int*类型 

int(*parr2)[10];

parr2是一个数组指针,该指针是指向数组的,指向的数组有10个元素,每个元素的类型是int 类型

int(*parr3[10])[5];

parr3是一个数组,是存放数组指针的数组,数组有10个元素;存放的这个数组指针,指向的数组有5个元素,每个元素是int类型 

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

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

相关文章

C++前缀和算法的应用:摘水果 原理源码测试用例

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 题目 在一个无限的 x 坐标轴上&#xff0c;有许多水果分布在其中某些位置。给你一个二维整数数组 fruits &#xff0c;其中 fruits[i] [positioni, amounti] 表示共…

读高性能MySQL(第4版)笔记20_Performance Schema和其他

1. 线程 1.1. MySQL服务端是多线程软件。它的每个组件都使用线程 1.2. 每个线程至少有两个唯一标识符 1.2.1. 操作系统线程ID 1.2.2. MySQL内部线程ID 2. 对象类型 2.1. OBJECT_TYPE列 2.2. EVENT 2.3. FUNCTION 2.4. PROCEDURE 2.5. TABLE 2.6. TRIGGER 3. Perfor…

RunnerGo UI自动化使用流程

可以直接进入官网下载开源版或点击右上角体验企业版体验 RunnerGo UI自动化平台 RunnerGo提供从API管理到API性能再到可视化的API自动化、UI自动化测试功能模块&#xff0c;覆盖了整个产品测试周期。 RunnerGo UI自动化基于Selenium浏览器自动化方案构建&#xff0c;内嵌高度…

Java并发线程池原理源码深入分析与调优实战

一&#xff0c;开篇&#xff1a; java中提供了多线程设计的Api&#xff0c;为什么还要用线程池呢&#xff1f; 下来看两个例子&#xff1a; 1. 使用多线程跑十万次 2. 使用线程池跑十万次 使用多线程跑十万次 package com.laoyang.ThreadPool.公开课;import java.util.ArrayL…

让图片完美适应:掌握 CSS 的object-fit与object-position

在CSS中&#xff0c;我们可以使用 background-size 和background-position属性为背景图像设置大小和位置。而 object-fit 和 object-position 属性则允许我们对嵌入的图像&#xff08;以及其他替代元素&#xff0c;如视频&#xff09;做类似的操作。在本文中&#xff0c;我们将…

Photoshop(PS)安装教程(图文教程超详细)

目录 一.简介 二.安装步骤 软件&#xff1a;PS版本&#xff1a;2023语言&#xff1a;简体中文大小&#xff1a;3.20G系统要求&#xff1a;Win10&#xff08;1903&#xff09;及以上版本&#xff0c;64位操作系统硬件要求&#xff1a;CPU2.0GHz 内存8G(或更高&#xff0c;不支…

蓝桥算法赛(铺地板)

问题描述 小蓝家要装修了&#xff0c;小蓝爸爸买来了很多块&#xff08;你可以理解为数量无限&#xff09; 23 规格的地砖&#xff0c;小蓝家的地板是 nm 规格的&#xff0c;小蓝想问你&#xff0c;能否用这些 23 的地砖铺满地板。 铺满地板&#xff1a;对于地板的每个区域&…

Apipost现已支持连接数据库!

Apipost提供了数据库连接功能&#xff0c;在接口调试时可以使用数据库获取入参或进行断言校验。目前的Apipost支持&#xff1a;Mysql、SQL Sever、Oracle、Clickhouse、达梦数据库、PostgreSQL、Redis、MongoDB 8种数据库的连接操作 新建数据库连接&#xff1a; 在「项目设置…

Openssl数据安全传输平台010:jasoncpp 0.10.7的编译 - Windows-vs2022 / Ubuntu/ Centos8 -含测试代码

文章目录 0. 代码仓库1 安装1.1 windows 下的安装1.2 Linux 下的安装1.2.1 相关环境配置问题1.2.2 准备安装1.2.2.1 安装scons1.2.2.2 安装jsoncppUbuntu系统下Centos8系统下 2 编译 c 测试文件&#xff1a; json-test.cpp2.1 配置库文件2.2 配置VS2.3 Winsows系统下cpp文件测试…

java集成海康预览抓图出现内存一直上涨问题

求助&#xff1a;在java 中集成海康sdk后批量抓图出现内存上涨问题&#xff0c;不论是预览后不关闭继续预览&#xff0c;还是预览后关闭预览&#xff0c;然后重新预览都没有解决这个问题&#xff08;抓图正常&#xff09;&#xff0c;尝试使用第三方解码器ffmpeg来进行解码&…

聊聊今年的秋招

大家好啊&#xff0c;我是董董灿。 又是一年秋招季&#xff0c;身边不少小伙伴反馈&#xff0c;今年的秋招很卷&#xff0c;很多人在刚到9月份的时候就开始投简历到处面试了。 不少同学甚至坐火车去外地参加笔试和面试&#xff0c;来回折腾的同时&#xff0c;也让周围的同学都…

[ACTF2020 新生赛]Include 1

题目环境&#xff1a;超链接&#xff0c;点进去看看你能找到flag吗&#xff1f;除了这些网页什么都没有&#xff0c;但是不当紧&#xff0c;因为我们有一双善于发现的眼睛&#x1f440;F12瞅瞅无&#xff0c;并无其他等等URL看了吗&#xff1f;发现存在一个参数file&#xff0c…

18 行为型模式-观察者模式

行为模式共有11种&#xff1a; 观察者模式 模板方法模式 策略模式 职责链模式 状态模式 命令模式 中介者模式 迭代器模式 访问者模式 备忘录模式 解释器模式 以上 11 种行为型模式&#xff0c;除了模板方法模式和解释器模式是类行为型模式&#xff0c;其他的全部属于对象行为型…

ShardingSphere-JDBC分库分表快速入门实战

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;My…

xhadmin多应用Saas框架如何安装情侣飞行棋?

xhadmin是什么&#xff1f; xhadmin 是一套基于最新技术的研发的多应用 Saas 框架&#xff0c;支持在线升级和安装模块及模板&#xff0c;拥有良好的开发框架、成熟稳定的技术解决方案、提供丰富的扩展功能。为开发者赋能&#xff0c;助力企业发展、国家富强&#xff0c;致力于…

设置爱奇艺代理教程

设置爱奇艺代理教程 活泼与直观&#xff1a;设置爱奇艺代理&#xff0c;让你的网络更加自由&#xff01; 轻松口语化&#xff1a;首先&#xff0c;打开爱奇艺APP&#xff0c;进入设置页面。 设置->网络->代理设置 活泼与直观&#xff1a;在代理设置页面&#xff0c;我…

Vue3富文本编辑器组件封装

近期后台项目有使用富文本编辑器的需求&#xff0c;本文记录一下封装细节 1.富文本组件库参考 TinyMCE - 富文本编辑器里的 Word &#xff0c;功能想不到的丰富tiptap - 多人在线实时协同编辑CKEditor 5 - 开源免费可商用&#xff0c;行内编辑Quill - 易扩展、轻量级二开、代码…

sql第二次上机作业

1查找借阅了ISBN为“4-6045-1023-4”的借书证号&#xff0c;读者姓名&#xff0c;专业名和借书时间 use tsgl go select Reader.Lno,Rname,Spec,Lend.Bordate FROM Reader,Lend WHERE Reader.LnoLend.Lno AND ISBN 4-6045-1023-42查找借阅了《数据库原理》一书的借阅信息&…

Kubernetes(K8S)快速搭建typecho个人博客

Kubernetes&#xff08;K8S&#xff09;快速搭建typecho个人博客 1、准备工作 K8S集群环境&#xff0c;搭建教程参考腾讯云Lighthouse组建跨地域Kubernetes集群 K8S集群面板&#xff0c;搭建教程参考Kubernetes集群管理面板的安装及使用 - 青阳のblog-一个计算机爱好者的个人…

[moeCTF 2023] pwn

总体上来说并不难&#xff0c;不过对于新生来说还是相当好的。循序渐进&#xff0c;很适合PWN入门到放弃。 baby_calculator 就是要算对100个10以内加法&#xff08;幼儿园的题&#xff09;练习pwntools和python from pwn import * from hashlib import md5 import string …