学C的第二十五天【指针的进阶】

news2024/11/11 6:53:32

=========================================================================

相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com)

=========================================================================

 接上期

学C的第二十四天【练习:1. 打印菱形;2. 打印自幂数;3. 求Sn=a+aa..n项之和;4. 喝汽水问题;5. 调整数组使奇数位于偶数前面;6. 打印X形图案;7……;8……;9……;10……】_高高的胖子的博客-CSDN博客

 =========================================================================

           

指针回顾:

一些指针相关知识:

            

(1). 指针是个用来存放地址的变量地址唯一标识的一块内存空间

内存划分为一个个的内存单元

每个内存单元有一个独立的编号,编号也称为地址

地址C语言中也被称为指针

指针(地址)需要存储起来,存储到变量中,这个变量被称为指针变量

               

               

(2). 指针(地址)的大小是固定的 4/8(32位操作系统/64位操作系统) 个字节

地址是由物理的电线产生的,

32位机器上,有32根地址线,每根会产生 1 或 0 的电信号

32个 1/0 组成一个二进制序列,将这个二进制序列当作地址

需要32个bit位(4个字节)才能存储这个地址,使用指针变量的大小就是4个字节

同理,在64位机器上,

地址是由64个 1/0 组成的二进制序列,需要64个bit位存储,即8个字节

使用这时指针变量的大小8个字节

               

            

(3). 指针是有类型的,指针的类型 决定了指针加减多少个整数的步长指针解引用操作时的权限

           

(4). 指针的运算指针加减整数指针减指针指针关系运算

             

往期指针相关文章:

学C的第五天(初识指针,内存产生内存单元地址过程,指针函数介绍和其大小;结构体补充)_高高的胖子的博客-CSDN博客

           

学C的第十七天【指针初阶: 1. 指针是什么?;2. 指针和指针类型;3. 野指针;4. 指针运算】_高高的胖子的博客-CSDN博客

            

学C的第十八天【指针初阶:5. 指针和数组、6. 二级指针、7. 指针数组;初识结构体:1. 结构体的声明、2. 结构体成员的访问、3. 结构体传参;练习:3道和整数二进制数相关的练习】_高高的胖子的博客-CSDN博客

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

1.字符指针:

(1). 含义:

字符指针指向字符变量指针存放字符变量的地址指针变量

                

(2). 字符指针的一种写法:存放指针变量

使用 取地址符& 取出字符变量的地址赋给 字符指针

              

(3). 字符指针的另一种写法:存放字符串表达式

实际上就是把 字符串表达式首字符地址(字符串表达式起始地址) 赋给 字符指针

              

这里说到了常量,补充一些关于常量的知识

               

(4). 一道相关笔试题:

           

对应代码:

#include <stdio.h>
int main()
{
	// 创建两个字符数组,一个叫str1,一个叫str2,
	// 只不过两个数组存储的内容相同,两个空间是相互独立的
	char str1[] = "hello world.";
	char str2[] = "hello world.";
	
	// str1数组 和 str2数组 是两个相互独立的空间
	// 所以两者指向的 首元素地址 是不同的
	if (str1 == str2)
		printf("str1 and str2 are same\n");
	else
		printf("str1 and str2 are not same\n");


	// 这两个是字符指针,“hello world”是一个常量字符串,不会改变
	// 所以只会为常量字符串开辟一个空间,指针使用时直接指向该字符串地址进行使用
	// 那么 str3 和 str4 应该是指向同一个空间(地址)的
	const char* str3 = "hello world.";
	const char* str4 = "hello world.";
	
	// 只会为常量字符串开辟一个空间,指针使用时直接指向该字符串地址进行使用
	// 那么 str3 和 str4 应该是指向同一个空间(地址)的
	if (str3 == str4)
		printf("str3 and str4 are same\n");
	else
		printf("str3 and str4 are not same\n");

	return 0;
}

               

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

2.指针数组:

(1). 含义:

指针数组一个数组,用于存放指针数组

                 

(2). 实例:

                  

(3). 使用指针数组模拟二维数组:

          

对应代码:

//使用指针数组模拟二维数组:
#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 };
	
	//使用指针数组存放3个数组名(数组首元素地址)
	int* arr[3] = { arr1,arr2,arr3 };

	//通过指针数组里的指针找到指针内容
	int i = 0;
	for (i = 0; i < 3; i++)
		//循环0-3,指针数组的下标0-3
	{
		int j = 0;
		for ( j = 0; j < 5; j++)
			//循环0-5,指针数组里指针内容的下标0-5
		{
			printf("%d ", arr[i][j]);
		}

		printf("\n"); //打印完一行后进行换行
	}

	return 0;
}

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

3.数组指针:

(1). 含义:

数组指针指向数组指针存放的是数组的地址指针变量

                   

例子:

int (*p)[10];

           

解释:

* 先和 结合,说明p是一个指针变量

指向的是 int [10] ,即一个大小为10的整型数组

所以 p 一个指针指向一个数组,叫做数组指针

               

(2). 数组名 对比 &数组名(取数组名地址)

         

数组名表示数组首元素地址,但有两个例外

          

1. sizeof(数组名),这里的数组名表示整个数组
计算整个数组的大小单位字节

           

2. &数组名,这里的数组名也表示整个数组
取出整个数组的地址整个数组的地址也是用数组首元素表示

&数组名 + 1 -- 会跳过整个数组,而不是 arr+1 跳过一个元素

                 

实例:

              

对应代码:

//数组名的理解:
//数组名表示数组首元素地址,但有两个例外
#include <stdio.h>
int main()
{
	int arr[10] = { 0 };

	//证明数组名是首元素地址:
	printf("%p\n", arr); //打印arr的地址
	printf("%p\n", &arr[0]); //打印&arr[0]的地址

	//换行:
	printf("\n");

	//数组名不表示首元素的两种例外:
	//1. sizeof(数组名),这里的数组名表示整个数组
	//	计算整个数组的大小,单位是字节
	printf("%d\n", sizeof(arr));

	//换行:
	printf("\n");

	//2. &数组名,这里的数组名也表示整个数组
	//	取出整个数组的地址
	printf("%p\n", arr); //打印arr的地址 -- int* 类型
	printf("%p\n", arr + 1);

	//换行:
	printf("\n");

	printf("%p\n", &arr[0]); //打印&arr[0]的地址 -- int* 类型
	printf("%p\n", &arr[0] + 1);

	//换行:
	printf("\n");

	printf("%p\n", &arr); //打印&arr的地址 -- int(*)[10]
	printf("%p\n", &arr + 1);


	return 0;
}

             

(3). 数组指针的初始化和使用:

           

1 . 数组指针的初始化:

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

            

实例:

              

 2 . 数组指针的使用:一般在二维(或以上)数组使用

              

(2.1). 对二维数组的补充理解:

二维数组每一行都可以理解为二维数组的一个元素

每一行又是一个一维数组

所以二维数组其实是一维数组的数组

              

(2.2). 二维数组的数组名:

二维数组数组名 也是 二维数组首元素的地址

数组首元素的地址 也是 二维数组第一行的地址

二维数组第一行的地址 是一个 一维数组的地址

可以通过 一维数组的地址 访问 一维数组的内容

         

实例:二维数组传参

            

对应代码:

//在二维数组中使用数组指针进行打印
#include <stdio.h>
void Print(int (*p)[5], int r, int c)
	//因为 二维数组数组名 是一个一维数组地址,
	//所以可以用 数组指针 作为形参
{
	int i = 0;
	for (i = 0; i < r; i++)
		//遍历二维数组的元素
	{
		int j = 0;
		for ( j = 0; j < c; j++)
			//遍历二维数组中每一行的元素
		{
			printf("%d ", *(*(p + i) + j));
			// *(p + 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(arr, 3, 5);
	//参数:(二维数组名,行数,列数)

	return 0;
}

                

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                  

4.数组传参和指针传参:

数组传参形参可以用 数组接收,也可以用 指针接收。)

(1). 一维数组传参:

                

(2). 二维数组传参:

                

指针传参形参只能用 指针接收。)

(3). 一级指针传参:

                

(4). 二级指针传参:

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

5.函数指针:

(1). 含义:

函数指针存放函数地址指针

         

(2). 函数也有地址:

                

(3). 函数指针的初始化和调用:

          

1 . 函数指针的 初始化:

               

2 . 函数指针的 调用:

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

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

相关文章

第三章——处理数据

面向对象编程&#xff08;OOP&#xff09;的本质是设计并扩展自己的数据类型。设计自己的数据类型就是让类型与数据匹配。在创建自己的类型之前必须先了解C内置的类型。 内置的C类型分为两组&#xff1a;基本类型和复合类型 简单变量 程序通常都需要存储信息&#xff0c;为把…

git commit history导出

git log --after"2022-1-1" --dateshort --prettyformat:"%H","%an","%ae","%ad","%s" --shortstat --no-merges再简洁一点 git log --after"2022-4-1" --dateshort --prettyformat:%H,%an,%ae,%ad,%…

Network Neuroscience:整个生命周期的功能连接体指纹

导读 随着年龄的增长&#xff0c;人脑功能结构发生了系统性的变化。然而&#xff0c;功能连接(FC)作为一种检测独特“连接体指纹”的强大特征&#xff0c;使个体能够在同龄人中被识别出来。虽然已在年轻人样本中观察到这种指纹&#xff0c;但该方法在整个生命周期内的可靠性尚…

ACL 2023|大模型时代,自然语言领域还有什么学术增长点?

国际计算语言学年会&#xff08;Annual Meeting of the Association for Computational Linguistics&#xff0c;简称 ACL&#xff09;是自然语言处理&#xff08;NLP&#xff09;领域的顶级国际会议&#xff0c;ACL 2023 将于2023年7月9-14日在加拿大多伦多举行。随着人工智能…

电脑高手的选择:为何只需一款杀毒软件?

对于电脑高手来说&#xff0c;保护计算机免受恶意软件和病毒的侵害至关重要。然而&#xff0c;有些人可能认为安装多个杀毒软件能够提供更优质的防护能力。但事实上&#xff0c;电脑高手通常只选择安装一款杀毒软件&#xff0c;这其中包含着一定的原因和考虑。本文将探讨为什么…

Java版本企业电子招投标采购系统源码功能模块功能描述+数字化采购管理 采购招投标

功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外部…

基于Python+MySQL所写的医院管理系统

点击以下链接获取源码资源&#xff1a; https://download.csdn.net/download/qq_64505944/87985429?spm1001.2014.3001.5503 目录 摘要 I 1 需求分析 1 1.1 任务描述 1 1.2 需求分析的过程 1 1.3 业务需求 2 1.4 功能描述 2 2 总体设计 3 2.1 系统开发环境 3 2.2 系统功能流…

【云原生】Pod 的生命周期

Pod 的生命周期 本文讲解的是 Kubernetes 中 Pod 的生命周期&#xff0c;包括生命周期的不同阶段、存活和就绪探针、重启策略等。 Pod phase Pod 的 status 字段是一个 PodStatus 对象&#xff0c;PodStatus中有一个 phase 字段。 Pod 的相位&#xff08;phase&#xff09;…

DOM事件机制(事件流、事件委托、事件类型)以及BOM

HTML DOM 允许 JavaScript 对 HTML 事件作出反应。JavaScript 能够在事件发生时执行&#xff0c;比如当用户点击某个 HTML 元素时。 JavaScript与HTML之间的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。 虽然 ECMAScript 把浏览器对象模型&…

【面试题28】什么是PHP-FPM?它与PHP和Nginx有什么关系

文章目录 一、前言二、什么是PHP-FPM&#xff1f;三、PHP-FPM的生命周期3.1 启动阶段3.2 初始化阶段3.3 请求处理阶段3.4 关闭阶段 四、PHP-FPM与PHP的关系五、PHP-FPM与Nginx的通信方式六、总结 一、前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP面试专区。 计划将全覆盖P…

【视觉SLAM入门】2.旋转--李群与李代数

"川泽纳污" 0. 一个例子1. 群和李群2. 李代数2.1 推导和性质2.2 s o ( 3 ) \mathscr{so(3)} so(3) 和 s e ( 3 ) \mathscr{se(3)} se(3)2.3 计算李代数的幂 e x p ( ϕ \;exp(\phi exp(ϕ^ ) ) )2.4 李代数乘法2.5 从李代数乘法到导数&#xff1a;2.5.1 直接求导2.…

100天精通Golang(基础入门篇)——第14天:深入解析Go语言函数->从概念到实践,助您精通基础知识!(基础)

&#x1f337; 博主 libin9iOak带您 Go to Golang Language.✨ &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &#x1f30a; 《I…

第11章:C语言数据结构与算法初阶之排序

系列文章目录 文章目录 系列文章目录前言排序的概念及其运用排序的概念常见的排序算法 常见排序算法的实现1.直接插入排序2. 希尔排序&#xff08;缩小增量排序&#xff09;3. 直接选择排序4. 堆排序5. 冒泡排序6. 快速排序将区间按照基准值划分为左右两半部分的常见方式&#…

使用selenium爬取猫眼电影榜单数据

文章目录 前言导入所需的库&#xff1a;设置ChromeDriver的路径&#xff0c;并创建一个Chrome浏览器实例&#xff1a;打开目标网页&#xff0c;这里以猫眼电影榜单页面为例&#xff1a;使用XPath定位电影信息。通过查看网页源代码&#xff0c;发现电影信息所在的<dd>标签…

深度学习之目标检测Faster RCNN模型算法流程详解说明(超详细理论篇)

1.Faster RCNN论文背景 2. Faster-RCNN算法流程 &#xff08;1&#xff09;Fast-RCNN算法流程 &#xff08;2&#xff09;特征提取conv layers &#xff08;3&#xff09;Region Proposal Networks(RPN) &#xff08;4&#xff09;ROI Pooling作用 &#xff08;5&#xff09;Cl…

Spring定时器调度实现的原理

1、使用Spring定时器任务实现 package com.suyun.modules.vehicle.timetask;import com.alibaba.schedulerx.worker.domain.JobContext; import com.alibaba.schedulerx.worker.processor.JavaProcessor; import com.alibaba.schedulerx.worker.processor.ProcessResult; impo…

arm学习cortex-A7中断按键控制led灯亮灭

main.c #include "key.h" extern void printf(const char *fmt, ...); void delay_ms(int ms) {int i,j;for(i 0; i < ms;i)for (j 0; j < 1800; j); } int main() {//rcc初始化 RCC->MP_AHB4ENSETR | (0x3 << 4);//初始化按键GPIOF模式为输入模式…

cyclo(-D-Ala-Val),15136-27-3,可以通过肽筛选发现的多肽

&#xff08;文章资料汇总来源于&#xff1a;陕西新研博美生物科技有限公司小编MISSwu&#xff09;​ 为大家介绍&#xff08;CAS&#xff1a;15136-27-3&#xff09;,试剂仅用于科学研究&#xff0c;不可用于人类&#xff0c;非药用&#xff0c;非食用。 英文名称&#xff1a…

从刷题到解决问题再到研究创新

题记&#xff1a;死的知识学再多也没大用。 明明自觉学会了不少知识&#xff0c;可真正开始做题时&#xff0c;却还是出现了“一支笔&#xff0c;一双手&#xff0c;一道力扣&#xff08;Leetcode&#xff09;做一宿”的窘境&#xff1f;你是否也有过这样的经历&#xff0c;题…

移动端H5页面引入高德地图的一些问题记录

web端显示 移动端显示 移动端和web端显示的地图范围一样大&#xff0c;并且在移动端地图的zoom和web端一致 这个问题是在公司开发邀请函的时候碰到的&#xff0c;因为要在移动端显示的范围足够大&#xff0c;使用zoom并不能满足需求了&#xff0c;例如如下代码 amap new AMa…