数组【有点难,要注重实战】

news2024/11/13 15:08:12

目录

  • 1. 一维数组的创建和初始化
    • 1.1 数组的创建
    • 1.2 数组的初始化
    • 1.3 一维数组的使用
    • 1.4 一维数组在内存中的存储
  • 2. 二维数组的创建和初始化
    • 2.1 二维数组的创建
    • 2.2 二维数组的初始化
    • 2.3 二维数组的使用
    • 2.4 二维数组在内存中的存储
  • 3. 数组越界
  • 4. 数组作为函数参数
    • 4.1 冒泡排序函数的错误设计
    • 4.2 数组名是什么?
    • 4.3 冒泡排序函数的正确设计
  • 5. 数据实例:
    • 5.1 数组的应用实例1:三子棋
    • 5.2 数组的应用实例2:扫雷游戏

1. 一维数组的创建和初始化

1.1 数组的创建

数组是一组相同类型元素的集合。
数组的创建方式:

type_t   arr_name   [const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小

数组创建的实例:

//代码1
int arr1[10];
//代码2
int count = 10;
int arr2[count];//数组时候可以正常创建?
//代码3
char arr3[10];
float arr4[1];
double arr5[20];

注:
数组创建,在C99标准之前,[ ]中要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念,数组的大小可以使用变量指定,但是数组不能初始化。

1.2 数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。
看代码:

int arr1[10] = {1,2,3};
int arr2[] = {1,2,3,4};
int arr3[5] = {12345};
char arr4[3] = {'a',98, 'c'};
char arr5[] = {'a','b','c'};
char arr6[] = "abcdef";

数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。
但是对于下面的代码要区分,内存中如何分配。

char arr1[] = "abc";
char arr2[3] = {'a','b','c'};

1.3 一维数组的使用

对于数组的使用我们之前介绍了一个操作符: [] ,下标引用操作符。它其实就数组访问的操作符。
我们来看代码:

#include <stdio.h>
int main()
{
    int arr[10] = {0};//数组的不完全初始化
     //计算数组的元素个数
    int sz = sizeof(arr)/sizeof(arr[0]);
     //对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
    int i = 0;//做下标
    for(i=0; i<10; i++)//这里写10,好不好?
      {
          arr[i] = i;
      } 
 //输出数组的内容
    for(i=0; i<10; ++i)
      {
         printf("%d ", arr[i]);
      }
    return 0;
}

总结:
1.数组是使用下标来访问的,下标是从0开始。
2.数组的大小可以通过计算得到。

int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);

1.4 一维数组在内存中的存储

接下来我们探讨数组在内存中的存储。
看代码:

#include <stdio.h>
int main()
{
  int arr[10] = {0};
  int i = 0;
  int sz = sizeof(arr)/sizeof(arr[0]);
    
  for(i=0; i<sz; ++i)
   {
      printf("&arr[%d] = %p\n", i, &arr[i]);
   }
  return 0;
}

请添加图片描述
仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。
由此可以得出结论:数组在内存中是连续存放的。
请添加图片描述

2. 二维数组的创建和初始化

2.1 二维数组的创建

//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];

2.2 二维数组的初始化

//数组初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略

2.3 二维数组的使用

二维数组的使用也是通过下标的方式。
看代码:

#include <stdio.h>
int main()
{
   int arr[3][4] = {0};
   int i = 0;
   for(i=0; i<3; i++)
    {
       int j = 0;
       for(j=0; j<4; j++)
         {
            arr[i][j] = i*4+j;
         }
    }
    for(i=0; i<3; i++)
    {
       int j = 0;
        for(j=0; j<4; j++)
           {
              printf("%d ", arr[i][j]);
           }
    }
    return 0;
}

2.4 二维数组在内存中的存储

像一维数组一样,这里我们尝试打印二维数组的每个元素。

#include <stdio.h>
int main()
{
    int arr[3][4];
    int i = 0;
    for(i=0; i<3; i++)
     {
        int j = 0;
        for(j=0; j<4; j++)
         {
             printf("&arr[%d][%d] = %p\n", i, j,&arr[i][j]);
         }
     }
    return 0;
}

请添加图片描述
通过结果我们可以分析到,其实二维数组在内存中也是连续存储的。
请添加图片描述

3. 数组越界

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

#include <stdio.h>
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int i = 0;
    for(i=0; i<=10; i++)
   {
        printf("%d\n", arr[i]);//当i等于10的时候,越界访问了
   }
 return 0;
}

二维数组的行和列也可能存在越界。

4. 数组作为函数参数

往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序(这里要讲算法思想)函数将一个整形数组排序。
那我们将会这样使用该函数:

4.1 冒泡排序函数的错误设计

//方法1:
#include <stdio.h>
void bubble_sort(int arr[])
{
 int sz = sizeof(arr)/sizeof(arr[0]);//这样对吗?
    int i = 0;
 for(i=0; i<sz-1; i++)
   {
        int j = 0;
        for(j=0; j<sz-i-1; j++)
       {
            if(arr[j] > arr[j+1])
           {
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
           }
       }
   }
}
int main()
{
    int arr[] = {3,1,7,5,8,9,0,2,4,6};
    bubble_sort(arr);//是否可以正常排序?
    int i = 0;
    for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
   {
        printf("%d ", arr[i]);
   }
    return 0;
}

方法1,出问题,那我们找一下问题,调试之后可以看到 bubble_sort 函数内部的 sz ,是1。
难道数组作为函数参数的时候,不是把整个数组的传递过去?

4.2 数组名是什么?

#include <stdio.h>
int main()
{
    int arr[10] = {1,23,4,5};
    printf("%p\n", arr);
    printf("%p\n", &arr[0]);
    printf("%d\n", *arr);
    //输出结果
    return 0;
}

结论:

数组名是数组首元素的地址。(有两个例外)

如果数组名是首元素地址,那么

int arr[10] = {0};
printf("%d\n", sizeof(arr));

为什么输出的结果是:40?
补充:

  1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。
  2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

除此1,2两种情况之外,所有的数组名都表示数组首元素的地址。

4.3 冒泡排序函数的正确设计

当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。
所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。
那么,函数内部的 sizeof(arr) 结果是4。
如果 方法1 错了,该怎么设计?

//方法2
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
 //代码同上面函数
}
int main()
{
    int arr[] = {3,1,7,5,8,9,0,2,4,6};
    int sz = sizeof(arr)/sizeof(arr[0]);
    bubble_sort(arr, sz);//是否可以正常排序?
    for(i=0; i<sz; i++)
   {
        printf("%d ", arr[i]);
   }
    return 0;
}

5. 数据实例:

5.1 数组的应用实例1:三子棋

(后面补链接)

5.2 数组的应用实例2:扫雷游戏

(后面补链接)

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

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

相关文章

JavaEE-一文了解IP协议与IP地址

目录 IP协议什么是IP地址IP地址的组成动态分配IPNAT机制(网络地址转换) IP协议 IP协议是不可靠、无连接的 不可靠:表示IP协议不能保证IP数据报能成功的到达目的地。IP仅提供传输服务&#xff0c;任何可靠性的要求都必须由上层来提供&#xff08;如TCP&#xff09;。如果传输过…

【C++|排序算法】冒泡、快排、归并、堆排序算法模版

目录 简介冒泡排序快速排序归并排序堆排序结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国…

字节跳动五面都过了,结果被刷了,问了hr原因竟说是...

摘要 说在前面&#xff0c;面试时最好不要虚报工资。本来字节跳动是很想去的&#xff0c;几轮面试也通过了&#xff0c;最后没offer&#xff0c;自己只想到几个原因&#xff1a;1、虚报工资&#xff0c;比实际高30%&#xff1b;2、有更好的人选&#xff0c;这个可能性不大&…

反垃圾邮件产品技术要求

声明 本文是学习信息安全技术 反垃圾邮件产品技术要求和测试评价方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 反垃圾邮件产品技术要求 引言 为指导反垃圾邮件产品的研制、生产、测试和评价工作的开展&#xff0c;本标准依据《信息技术 安全技…

基于Spring注解 + MyBatis + Servlet 实现数据库交换的小小Demo

基于Spring注解 MyBatis Servlet 实现数据库交换的小小Demo 第一步 创建web 项目&#xff0c;这一步省略&#xff0c;有不会的可以参考之前发布的文档 第二步 配置pom.xml文件 <dependencies><!-- Spring常用依赖 --><dependency><groupId>org.spr…

SpringCloud --- Eureka注册中心

一、场景 假如我们的服务提供者user-service部署了多个实例&#xff0c;如图 思考几个问题&#xff1a; order-service在发起远程调用的时候&#xff0c;该如何得知user-service实例的ip地址和端口&#xff1f; 有多个user-service实例地址&#xff0c;order-service调用时该…

【LeetCode】剑指 Offer 67. 把字符串转换成整数 p318 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/ 1. 题目介绍&#xff08;67. 把字符串转换成整数&#xff09; 写一个函数 StrToInt&#xff0c;实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。 …

day1 什么是互联网

目录 计算机网络的定义与分类 网络的网络 互联网的组成 互联网的边缘部分 互联网基础结构发展的三个阶段 第一阶段&#xff08;1969 - 1990&#xff09; 第二阶段&#xff08;1985 - 1993&#xff09; 第三阶段&#xff08;1993 - 现在&#xff09; 20世纪90年代&#xff…

项目经验总结——送给测试岗做项目的朋友们

目录 前言 1、项目排期时的时间预估能力欠佳 2、QA写单元测试 3、集成测试方案不够精简 4、排了优先级也很难取舍 5、搭完redis集群却不了解redis运行机制 总结 结语 前言 最近负责的L项目从3月初开始开发到6月底正式上线&#xff0c;这是我在工作快1年时间里第一次独…

机械键盘、口袋打印机,万元奖金等你拿!「万象格新」AI绘画X海报设计大赛即将开启...

号外&#xff01;「万象格新」大赛开启 如果阳光暖到你心里&#xff0c;那一定是一格在想你~ 春夏交替&#xff0c;万物焕发生机&#xff0c;明媚色彩娱情惬意 在这样一个美好的时节 如果你&#xff1a; 心中荡漾着色彩斑斓的 AI 绘画创意 想要 show 出独到的审美与非凡设计能力…

【系统集成项目管理工程师】项目干系人管理

&#x1f4a5;十大知识领域&#xff1a;项目干系人管理 项目干系人管理包括以下 4 个过程: 识别干系人规划干系人管理管理干系人参与控制干系人参与 一、识别干系人 输入工具与技术输出项目章程采购文件事业环境因素组织过程资产组织相关会议专家判断干系人分析干系人登记册 …

servlet(1)—javaEE

文章目录 1.认识servlet2.使用servlet2.1创建项目2.2引入依赖2.3创建目录2.4编写代码2.5打包2.6部署2.7运行2.8验证 3.开发步骤4.部署方式4.1打包4.2安装插件 5.访问出错的情况5.1 4045.2 4055.3其他 6.servlet的三大生命周期方法7.servlet api7.1HttpServlet7.2HttpServletReq…

想攀登金融领域高峰,中国人民大学与加拿大女王大学金融硕士是重要途径

每个人都希望自己的职场攀登是优质路线&#xff0c;最短路线。金融业招聘注重学历&#xff0c;最早外资投资银行招聘只要清北复交&#xff0c;现在知名金融机构工作也只招985。还有一个特点是&#xff0c;宁要国内清北复交&#xff0c;也不要海归留学。学历到底重不重要&#x…

响应式布局

文章目录 响应式布局概述viewport 视口CSS 常用单位CSS 媒体查询语法直接使用使用style标签使用link引入 自适应布局栅格系统响应式布局案例rem媒体查询 响应式布局 概述 响应式布局是指网站或应用程序可以自适应不同的屏幕尺寸和设备类型&#xff0c;简而言之就是一个网站兼…

ERTEC200P-2 PROFINET设备完全开发手册(8-2)

8.2 IRT通讯原理及API PROFINET RT通讯的特点&#xff1a; 典型的PROFINET网络如下图所示。 其中&#xff1a; T1: 采样输入 T2: IO背板周期 T3: Profinet I/O 通讯周期 T4: CPU组织块OB1执行周期 T5: Profinet I/O 通讯周期 T6: IO背板周期 T7: 建立输出 在PRO…

Java35-85

这里写目录标题 steam流collect超详解 方法引用静态方法中没有this&#xff01;&#xff01;&#xff01;引用本类或者父类的成员方法 引用构造方法引用方法成员引用数组的构造方法转成自定义对象获取部分属性并收集到数组 异常异常中的常见方法抛出 处理自定义异常File的概述和…

实验8 梯度下降法

1. 实验目的 ① 掌握深度学习框架中的自动求导机制&#xff1b; ② 掌握梯度下降法的基本原理&#xff0c;能够使用梯度下降法求解一元和多元线性回归问题。 2. 实验内容 ① 使用TensorFlow的可训练变量和自动求导机制实现梯度下降法&#xff1b; ② 使用梯度下降法训练线性…

2023-04-23 算法面试中常见的动态规划问题

动态规划 1 什么是动态规划 以菲波那切数列求和为例&#xff0c;通过 1.普通的递归2.引入记忆数组memo3.自下而上地解决问题&#xff0c;即动态规划 动态规划的定义 dynamic programming (also known as dynamic optimization) is a method for solving a complex problem by…

Redis-cli Go代码

Redis-cli Go代码 安装 go get github.com/redis/go-redis/v9 建立连接 import ("context""fmt""github.com/redis/go-redis/v9" )client : redis.NewClient(&redis.Options{Addr: "localhost:6379",Password: "", …

支付宝 网站支付Demo 案例【沙箱环境】IDEA如何配置启动Eclipse项目

前言 在跑支付宝提供的支付案例Demo的时候&#xff0c;遇到了一些问题。支付宝提供的Demo是用Eclipse跑的JAVAEE项目。我想用IDEA来跑一下看看、结果使用习惯了Mavne管理jar包和SpringBoot项目。启动web项目的时候&#xff0c;还遇到一些问题。特此记录遇到的一些小问题。顺便回…