当前位置: 首页 > news >正文

鹏哥C语言55-57---二维数组+数组越界+数组传参(冒泡排序)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//---------------------------------------------------------------------------------------2.   二维数组的创建和初始化

//-------------------------------------------------------------------------------------------------2.1 二维数组的创建
// 1 2 3 4 
// 2 3 4 5
// 3 4 5 6

int main()
{int arr1[3][4]; // (3行4列)char arr2[5][10]; // (5行10列)double arr3[6][6]; // (6行6列)return 0;
}

//-------------------------------------------------------------------------------------------------2.2 二维数组的初始化

int main()
{int arr1[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 }; // 1 2 3 4//  2 3 4 5//   3 4 5 6  int arr2[3][4] = { 1,2,3,4,2,3,4,5,3,4 };  // 如果元素不够,用0补齐(不完全初始化)//  1 2 3 4//  2 3 4 5//  3 4 0 0   int arr3[3][4] = { {1},{2,3},{3,4,5} };  // 可以再分组(不完全初始化)//  1 0 0 0//  2 3 0 0//  3 4 5 0   //二维数组  可以省略 行 数,不能省略 列 数int arr3[][4] = { {1,2,3,4},{2,3} }; //行数输入了几行,就是几行//  1 2 3 4//     2 3 0 0  return 0;
}

//-------------------------------------------------------------------------------------------------2.3 二维数组的使用
// 二维数组的使用也是通过下标的方式
//不管是 行 还是 列 都是从0开始访问

int main()
{//int arr1[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 };//----------------------------------------------------自己 输入一个 二维数组int arr1[3][4] = { 0 }; int i = 0;for (i = 0; i <3; i++){int j = 0;for (j = 0; j <4; j++){scanf("%d", &arr1[i][j]);}}//---------------------------------------------------- 打印 整个 二维数组for (i = 0; i <= 2; i++){int j = 0;for (j = 0; j <= 3; j++){printf("%d ", arr1[i][j]);}printf("\n");}//--------------------------------------------------------打印数组中的某个元素printf("%d\n", arr1[2][2]); // 打印 3行 3列 位置的元素printf("%d\n", arr1[2][0]); // 打印 3行 1列 位置的元素return 0;
}

//可以把二维数组理解为由一维数组组成的数组
访问第一行元素 arr[0][j]
访问第二行元素 arr[1][j]
访问第三行元素 arr[3][j]

//-----------------------------------------------------------------------------------------2.4 二维数组在内存中的存储
// 打印出 二维数组中的地址

int main()
{int arr1[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 };int i = 0;for (i = 0; i <= 2; i++){int j = 0;for (j = 0; j <= 3; j++){printf("&arr1[%d][%d]=%p\n", i,j,&arr1[i][j]);}}return 0;
}

//二维数组在内存中也是 连续存放的,各相差4个字节(一个字符四个字节)
&arr1[0][0]=00000027016FF598
&arr1[0][1]=00000027016FF59C
&arr1[0][2]=00000027016FF5A0
&arr1[0][3]=00000027016FF5A4
&arr1[1][0]=00000027016FF5A8
&arr1[1][1]=00000027016FF5AC
&arr1[1][2]=00000027016FF5B0
&arr1[1][3]=00000027016FF5B4
&arr1[2][0]=00000027016FF5B8
&arr1[2][1]=00000027016FF5BC
&arr1[2][2]=00000027016FF5C0
&arr1[2][3]=00000027016FF5C4


//二维数组  可以省略行数,不能省略 列 数
// int arr[][4]={1,2,3,4,5,6};


//---------------------------------------------------------------------------------------------------------------3.数组越界
数组的下标是有范围限制的。
数组的下标规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,
所以程序员写代码时,最好自己做越界的检查。

//------------------------------------------------一维

int main()
{int arr1[] = { 1,2,3,4,5,6 };int sz = sizeof(arr1) / sizeof(arr1[0]); //用公式计算得到数组大小int i = 0;for (i = 0; i < sz; i++) //写 sz 避免出现数组越界访问
//    for (i = 0; i < 9; i++) // 数组越界{printf("%d ", arr1[i]);}return 0;
}

//-----------------------------------------------二维

int main()
{int arr1[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 };int i = 0;for (i = 0; i <3; i++){int j = 0;for (j = 0; j <4; j++)// for (j = 0; j <= 4; j++) //数组越界{printf("%d ", arr1[i][j]);}printf("\n");}return 0;
}

//--------------------------------------------------------------------------------------------------4.数组作为函数参数
//写代码时,常常会将数组作为参数传给函数。比如实现一个冒泡程序
//冒泡排序的核心思想,两个相邻的元素进行比较
//一趟冒泡排序让一个数据来到他最终应该出现的位置

//----------------------------------------------------------------------------------------4.1 冒泡排序函数的错误设计
//数组传参,形参有两种写法: 1.数组  2.指针

//-------------------------------------失败原因------------------------------------
数组传参传的是数组内元素的首地址
地址应该使用指针来接收
所以 这里的 形参 int arr[],表面上是数组,本质上是个指针变量
因此  sizeof(arr) 计算出来的就不是数组大小了,是指针大小4(x86环境)
sizeof(arr[0]) 也是4 
所以 sz 求出来为 1,导致冒泡失败
修改方法,把 sz 放到函数外部求,传到函数内部

void bubble_sort(int arr[], int sz)  // 1. 形参是数组形式:便于理解。 []数值可写可不写
//void bubble_sort(int* arr, int sz)   // 2. 形参是指针形式{//确定需要多少趟冒泡排序(也就是数组元素个数-1)//int sz = sizeof(arr) / sizeof(arr[0]); //失败原因,解决方法就是sz 在外部求,传到内部 -----------0 1 2 3 4 5 6 7 8 9 -----冒泡成功int i = 0;for (i = 0; i < sz - 1; i++) //sz-1趟冒泡排序{//一趟冒泡排序int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){//交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}//void bubble_sort(int* arr)  // 2. 形参是指针形式:
//{
//
//}int main()
{//把数组内容排成升序int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);//冒泡排序算法,对数组进行排序//bubble_sort(arr); // 数组名本质是数组首元素的地址---------------------------失败原因bubble_sort(arr,sz); //数组传参,给数组名就行,把数组元素个数也传过去// 打印出来int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);  // 8 9 7 6 5 4 3 2 1 0-------------------------冒泡失败}return 0;
}

//------------------------------------------------------------------------------------------------4.2 数组名是什么?
//数组名确实能表示首元素的地址
//但是有两个例外
// 1. sizeof(数组名),  这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
// 2. &数组名,           这里的数组名也表示整个数组,取出的是 整个数组的地址
//除了这两种情况之外,以后见到的所有的  数组名arr, 代表的都是首元素地址

int main()
{int arr[10];printf("%p\n", arr);    // 打印数组名    arr 首元素的地址printf("%p\n", arr+1);printf("---------------------------------------\n");printf("%p\n", &arr[0]); //打印首元素地址printf("%p\n", &arr[0]+1);printf("---------------------------------------\n");printf("%p\n", &arr);    //  打印数组的地址printf("%p\n", &arr+1);// 000000148B8FFB78  //跳了4个字节,1个元素// 000000148B8FFB7C// -------------------------------------- -// 000000148B8FFB78 //跳了4个字节,1个元素// 000000148B8FFB7C// -------------------------------------- -// 000000148B8FFB78   //跳了40个字节,整个数组的10个字节// 000000148B8FFBA0int n = sizeof(arr);printf("%d\n", n);    // 算出 40,数组的大小,40个字节return 0;
}

//------------------------------------二维数组数组名的理解

int main()
{int arr[3][4];int sz = sizeof(arr); //计算整个元素的大小     12个元素,每个元素4个字节printf("%d\n", sz);  // 输出 48 (3*4*4)arr; // 二维数组的数组名 表示的是 第一行(首行) 的地址,不是0*0元素的地址printf("%p\n", arr);printf("%p\n", arr + 1);// 000000A2C0AFFCC8  跳过16个字节,4个元素,也就是跳过一行//    000000A2C0AFFCD8printf("%d\n", sizeof(arr) / sizeof(arr[0]));             //计算数组的行数(数组所有字节 / 数组每行的字节数)printf("%d\n", sizeof(arr[0]) / sizeof(arr[0][0]));  //计算数组的行数(数组首行字节数 / 数组一个字节数)return 0;
}


 

相关文章:

  • 婚恋交友小程序的设计思路与用户体验优化
  • JavaScript 从事件处理入手的优化
  • 《征服数据结构》哈夫曼树(Huffman Tree)
  • 鸿蒙开发(NEXT/API 12)【硬件(外设扩展驱动开发)】驱动开发服务
  • 【百日算法计划】:每日一题,见证成长(021)
  • IP地址如何与网络虚拟化技术融合?
  • AQS为什么采用双向链表
  • Linux 块设备开发学习
  • 8个前端小程序开发框架的介绍
  • 【JAVA开源】基于Vue和SpringBoot的足球俱乐部管理后台
  • 记一次停车场后台管理系统漏洞挖掘
  • 让具身智能更快更强!华东师大上大提出TinyVLA:高效视觉-语言-动作模型,遥遥领先
  • 小麦生长状态检测系统源码分享
  • 第十章 【后端】商品分类管理微服务 > 分类列表查询接口(10.8.3)——MyBatis-Plus 逻辑删除
  • Ansible 剧本的执行
  • Android 架构优化~MVP 架构改造
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • JAVA之继承和多态
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • js中的正则表达式入门
  • Linux链接文件
  • React-Native - 收藏集 - 掘金
  • Vim 折腾记
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 深入 Nginx 之配置篇
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 首页查询功能的一次实现过程
  • 小而合理的前端理论:rscss和rsjs
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 白色的风信子
  • ​Linux·i2c驱动架构​
  • ​渐进式Web应用PWA的未来
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • ${factoryList }后面有空格不影响
  • (1)(1.9) MSP (version 4.2)
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (ros//EnvironmentVariables)ros环境变量
  • (vue)页面文件上传获取:action地址
  • (八十八)VFL语言初步 - 实现布局
  • (笔试题)分解质因式
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (文章复现)基于主从博弈的售电商多元零售套餐设计与多级市场购电策略
  • *Django中的Ajax 纯js的书写样式1
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .Net FrameWork总结
  • .Net中的集合
  • @antv/x6 利用interacting方法来设置禁止结点移动的方法实现。
  • @Autowired多个相同类型bean装配问题
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思