【理解指针(三)】

文章目录

  • 一、数组名的理解
      • (1)数组的地址与数组首元素地址的区别
  • 二、使用指针访问数组
      • (1)一维数组传参的本质
  • 三、冒泡排序
      • (1)什么是冒泡排序
      • (2)写冒泡排序
  • 四、结束语

一、数组名的理解

首先回顾一下指针访问数组的内容:

int arr[]={1,2,3,4,5,6,7,8,9};
int * pa=&arr[0];//pa是指针变量

这里一个&arr[0],它是指数组首元素的地址,但是数组名也是地址,并且也是数组首元素的地址,
我们可以做个简单的测试:

#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9 };int* ps = &arr[0];printf("arr=%p\n", arr);printf("&arr[0]=%p\n", &arr[0]);return 0;
}

在这里插入图片描述
由运算结果就可以得出我们的结论:数组名是首元素的地址。

有两个特例的地方:

#include<stdio.h>
#include<string.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9 };int* pa = &arr[0];printf("%d", sizeof(arr));return 0;
}

输出的结果是36,大家可能会想arr如果是地址的话,在不同的环境下输出的结果会不同(也就是在x86或者在x64的环境),那应该输出4或者8才对。

对于上面的代码可能大家会有些不理解了,其实这是arr的特殊情况之一。

sizeof(arr) : sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节。

#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9 };int* pa = &arr[0];printf("%p\n", &arr);return 0;
}

这里的**&数组名**,这里是的数组名表示的是整个数组,取出的是整个数组的地址(整个数组的地址与首元素的地址是有区别的,可以+1试试看,结果不同)。

除此之外,任何地方使用数组名,数组名都表示首元素的地址。

(1)数组的地址与数组首元素地址的区别

#include<stdio.h>
int main()
{int str[] = { 1,2,3,4,5,6,7,8,9,10 };printf("&str[0]   = %p\n", &str[0]);printf("&str[0]+1 = %p\n", &str[0]+1);printf("&str      = %p\n", &str);printf("&str+1    = %p\n", &str+1);return 0;
}

这里的&str[0]+1就是跳过⼀个元素

但是&str和&str+1相差40个字节,这就是因为&str是数组的地址,+1操作是跳过整个数组的。

在这里插入图片描述

二、使用指针访问数组

例子,我们写一个代码来输出数组,要求要使用到指针:

#include<stdio.h>
void V_copy(int* str, int len)
{for (int i = 0; i < len; i++){printf("%d ", *str);str++;}printf("\n");
}
int main()
{int str[] = { 2,4,5,6,1,7,4,9,3,0,8 };int* pa = &str[0];int len = sizeof(str) / sizeof(str[0]);V_copy(str, len);return 0;
}
printf("%d ", *str);str++;

我们可以把这里改写成:printf(“%d”,*(str+i)) 的形式,本质上和上面的那个形式是一样的。

*(str+i)换成str[i]也是能够正常打印的,所以本质上str[i]是等价于*(str+i)。

如果我们想要有自己的输入,那么我们可以加上下面的代码:

for (int i = 0; i < len; i++)
{scanf("%d", pa + i);
}

我们最后的代码,也可以写成下面的形式:

#include<stdio.h>
int main()
{int str[10] = { 0 };int* pa = &str[0];int len = sizeof(str) / sizeof(str[0]);for (int i = 0; i < len; i++){scanf("%d", pa + i);}for (int i = 0; i < len; i++){printf("%d ", *(pa + i));}return 0;
}

(1)一维数组传参的本质


#include<stdio.h>
void Print(int arr[])
{int len1 = sizeof(arr) / sizeof(arr[0]);int sz2 = len1;printf("sz2=%d\n", sz2);}
int main()
{int arr[] = { 1,1,2,3,4,5,6,7,8,9 };int len = sizeof(arr) / sizeof(arr[0]);int sz = len;printf("sz=%d\n", sz);Print(arr);return 0;
}

在这里插入图片描述
由结果我们可以发现函数的内部并没有得到正确的数组元素个数。

由上面 的知识我们可以知道:数组名是数组首元素的地址,数组传参我们传递的是数组名,也就

是说本质上数组传参传递的是数组首元素的地址。

函数参数本质上是指针,所以函数内部没办法求数组元素的个数。

所以这里的 void Print(int arr[])我们可以改写成void Print(int*arr)(这个是指针的形式

三、冒泡排序

(1)什么是冒泡排序

冒泡排序就是指相邻的两个数作比较,根据你想要的结果最后输出;比如,我想要输出1,3,5,2,7,8,6,4,9这几个数字的升序,那么我们就需要先1很3比较,3大于1,所以3和1的位置不交换,再3和5比较,5是大于3的也不交换,再2和5 比较,5大于2,5应该在2的后面,所以5和2比较,以此类推;当第一次轮完后,也就是知道最后一个数字是9之后,我们再来第二次的比较,此时,数字9的位置不再改变,因为它就是最大的,且位于这个数组的最后一个位置。

在这里插入图片描述

(2)写冒泡排序

#include<stdio.h>
void Button_c(int *str, int len)
{for (int i = 0; i < len - 1; i++){for (int j = 0; j < len - 1 - i; j++){if (*(str+j) > *(str + j+1)){int tem = *(str+j);*(str+j) = *(str + j+1);*(str +j+1) = tem;}}}}
void print(int* str, int len)
{for (int i = 0; i < len; i++){printf("%d ", *(str + i));}
}
int main()
{int str[10] = { 1,4,2,3,7,5,6,8,9,10 };int len = sizeof(str) / sizeof(str[0]);Button_c(str, len);print(str,len);return 0;
}

上面的代码可以输出我们想要的结果,感觉编译器进行比较的次数有点多,因为它会反复比较即使位置是符合升序的数字,这就是上面代码的弊端。

所以我们简单的进行一些优化,设一个变量flage,假设flage=1表示这相邻的两个数符合升序,不需要交换;如果相邻的两个数进行了交换,那我们就可以改变flage的值,可以让它被赋值为0,因此,我们可以进行以下操作:

#include<stdio.h>
void Button_c(int* str, int len)
{for (int i = 0; i < len - 1; i++){int flage = 1;for (int j = 0; j < len - 1 - i; j++){if (*(str + j) > *(str + j + 1)){int tem = *(str + j);*(str + j) = *(str + j + 1);*(str + j + 1) = tem;flage = 0;}}if (flage == 1){break;}}
}
void print(int* str, int len)
{for (int i = 0; i < len; i++){printf("%d ", *(str + i));}
}
int main()
{int str[10] = { 1,4,2,3,7,5,6,8,9,10 };int len = sizeof(str) / sizeof(str[0]);Button_c(str, len);print(str, len);return 0;
}

四、结束语

关于冒泡排序就到这里了,后续我会继续写关于冒泡排序的改进版本。

大家不理解的地方可以自己再反复看看,或者查查资料,希望可以和大家一起进步!!!!

在这里插入图片描述

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

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

相关文章

堆排序(向下调整法,向上调整法详解)

目录 一、 二叉树的顺序结构 二、 堆的概念及结构 三、数组存储、顺序存储的规律 此处可能会有疑问&#xff0c;左右孩子的父节点计算为什么可以归纳为一个结论了&#xff1f; 四、大小堆解释 五、大小堆的实现&#xff08;向上和向下调整法&#xff09; 5.11向上调整法…

Unity Timeline学习笔记(1) - 创建TL和添加动画片段

Timeline在刚出的时候学习了一下&#xff0c;但是因为一些原因一直都没用在工作中使用。 版本也迭代了很久不用都不会用了&#xff0c;抽时间回顾和复习一下&#xff0c;做一个笔记后面可以翻出来看。 创建Timeline 首先我们创建一个场景&#xff0c;放入一个Plane地板&#…

Linux操作系统-08-常用的网络相关命令

1、ping命令 在linux下ping的话会一直ping下去&#xff0c;在windows下的话它会只ping四次就结束&#xff0c; [rootbastion ~]# ping 192.168.0.102 PING 192.168.0.102 (192.168.0.102) 56(84) bytes of data. 64 bytes from 192.168.0.102: icmp_seq1 ttl64 time0.571 ms…

Linux - 线程互斥和互斥锁

文章目录 前言一、为什么要线程互斥原子性 二、互斥锁互斥锁的创建与销毁互斥锁进行互斥 前言 前几节课&#xff0c;我们学习了多线程的基础概念&#xff0c;这节课&#xff0c;我们来对线程互斥和互斥锁的内容进行学习。 一、为什么要线程互斥 首先我们要明白&#xff0c;对…

悲观锁(Pessimistic Locking)是一种数据库锁定机制

悲观锁&#xff08;Pessimistic Locking&#xff09;是一种数据库锁定机制&#xff0c;用于防止多个事务同时修改同一数据记录。以下是关于悲观锁的一些详细信息&#xff1a; 锁定数据&#xff1a;当事务对一条记录进行操作时&#xff0c;悲观锁会阻止其他事务对这条记录进行修…

Matplotlib数据可视化实战-1数据可视化Matplotlib基础

1.1绘图的一般过程&#xff1a; 1.导入相关库 2.生成、读入或计算得到数据&#xff1b; 3.根据需要绘制折线图、散点图、柱状图、饼状图、雷达图、箱线图、三维曲线/曲面以及极坐标系图形&#xff1b; 4.根据需要设置图形属性&#xff1b; 5.显示或保存绘图结果。 例如&…

c语言大小写字母的转换

通过ascll码表我们可以知道大写字母与小写字母相差32个数&#xff08;小写字母比大写字母大&#xff09;。因此&#xff0c;通过相加减32即可转换大小写字母。 #include <stdio.h>int main() {char ch c;char CH A;printf("%c\n", ch - 32);printf("%c…

计算机网络实验——学习记录

1. tun/tap模块&#xff1a;为Linux系统提供网络虚拟功能&#xff0c;tun位于网络OSI模型的三层&#xff08;网络层&#xff09;&#xff0c;tap位于网络的二层&#xff08;数据链路层&#xff09;。 1.1 验证是否包含tun/tap模块&#xff1a;modinfo tun&#xff1b; 1.2 验…

Python进程与线程开发

目录 multiprocessing模块 线程的开发 threading模块 setDaemon 死锁 线程间的通信 multiprocessing模块 运行python的时候&#xff0c;我们都是在创建并运行一个进程&#xff0c;(linux中一个进程可以fork一个子进程&#xff0c;并让这个子进程exec另外一个程序)。在pyt…

全局路径规划算法 - 动态规划算法Python实现

参考博客&#xff1a; &#xff08;1&#xff09;算法数据结构——动态规划算法&#xff08;Dynamic Programming&#xff09;超详细总结加应用案例讲解 &#xff08;2&#xff09;【路径规划】全局路径规划算法——动态规划算法&#xff08;含python实现&#xff09; &#xf…

【上交主办·EI会议】| 2024年模式分析与机器智能国际会议 (ICPAMI 2024)

会议简介 Brief Introduction 2024年模式分析与机器智能国际会议(ICPAMI 2024) 会议时间&#xff1a;2024年8月30日-9月1日 召开地点&#xff1a;中国上海 大会官网&#xff1a;www.icpami.org ICPAMI 2024将围绕“模式分析与机器智能”的最新研究领域展开&#xff0c;为研究人…

(零)OpenOFDM接收端整体思路

一旦捕获射频信号并将其下变频至基带&#xff0c;解码管道就会启动&#xff0c;包括&#xff1a; OFDM&#xff0c;多载波调制的一种。通过频分复用实现高速串行数据的并行传输, 它具有较好的抗多径衰落的能力&#xff0c;能够支持多用户接入。 OFDM主要思想是&#xff1a;将信…

Finding the Majority Element寻找主元素

Problem Is there the majority element in sequence A [1.. n]? If so, please find it out. An integer a in A is called the majority if it appears more than [n/2] times in A.寻找元素出现次数大于n/2 Algorithm 1 —— The brute-force method 遍历序列中的每个元…

物联网数据驾驶舱

在信息化时代&#xff0c;数据已经成为驱动企业发展的核心动力。特别是在物联网领域&#xff0c;海量数据的实时采集、分析和监控&#xff0c;对于企业的运营决策和业务优化具有至关重要的作用。HiWoo Cloud作为领先的物联网云平台&#xff0c;其数据监控功能以“物联网数据驾驶…

Docker常见指令

1.docker search mysql &#xff1a;从docker镜像仓库搜索和mysql有关的镜像 docker search mysql 2.docker pull mysql &#xff1a;从docker仓库拉取mysql镜像 docker pull mysql 3.docker run mysql &#xff1a;启动mysql镜像 docker run mysql 4.docker ps &#xff…

工业母机5G智能制造工厂数字孪生可视化平台,推进行业数字化转型

随着科技的不断进步和工业的快速发展&#xff0c;数字化转型已成为工业领域的重要趋势。工业母机作为制造业的核心设备&#xff0c;其智能化、自动化水平的提升对于整个工业的发展具有重要意义。5G技术的广泛应用&#xff0c;为智能制造工厂提供了更为可靠、高速的网络连接&…

OSError: We couldn‘t connect to ‘https://huggingface.co‘ to load this file

想折腾bert的同学&#xff0c;应该也遇到这个问题。 一、报错信息分析 完整报错信息&#xff1a;OSError: We couldnt connect to https://huggingface.co to load this file, couldnt find it in the cached files and it looks like google/mt5-small is not the path to a…

力扣刷题Days20-151. 反转字符串中的单词(js)

目录 1,题目 2&#xff0c;代码 1&#xff0c;利用js函数 2&#xff0c;双指针 3&#xff0c;双指针加队列 3&#xff0c;学习与总结 1&#xff0c;正则表达式 / \s /&#xff1a; 2&#xff0c;结合使用 split 和正则表达式&#xff1a; 1,题目 给你一个字符串 s &am…

Docker学习之使用harbor搭建私有仓库(超详解析)

实验目的&#xff1a; 使用centos7&#xff0c;基于harbor构建私有仓库 实验步骤&#xff1a; 下载相关安装包和依赖&#xff1a; [rootlocalhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2 wget //安装docker所需要的相关依赖 [rootlocalhost ~]#…

山景BP1048 升级狗烧写

1.打开MVAssistant_BP10xx工具&#xff0c;在芯片型号栏中选择B1X系列。 2.模式选择 选 M2.仅升级Flash SH(可选) 3 .Code数据选择SDK编译好的bin文件 4.const数据选择编译好的提示音bin文件。 5.点击升级狗下载。 6. 如下图所示&#xff0c;出现提示为正在给升级狗正在下载程…