C语言教程——数组(1)


目录

系列文章目录

前言

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

1.1数组的创建

1.2数组的初始化

1.3一维数组的使用

总结

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

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

2.1二维数组的创建

 2.2二维数组的初始化

2.3二维数组的使用

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

3、数组越界

总结


前言

本篇文章开启数组的学习。


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

1.1数组的创建

数组是一组相同类型元素的集合。

数组的创建方式:

type_t  arr_name  [const_n];

//type_t 是指数组的元素类型
//const_n 是一个常亮表达式,用来指数组的大小

类似下面的:

 根据实际情况,假如我要一个空间放5个的字符类型的名字为arr的数组:

char arr2[5];

类型为双精度浮点数放八个名字为arr3的数组:

double arr3[8];

 可以指定元素类型,元素个数和名称。

数组创建的时候里面放置一个常量(标准形式)才可以,常量表达式也可以。

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

当我们在VS里面用变量,就会报错,所以VS不支持这个变长数组的使用。

1.2数组的初始化

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

数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。

完全初始化: 

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

不完全初始化:

int arr2[10]={1,2,3};

不完全初始化的时候,后面没有给数的元素默认初始化为0.

没有指定数组元素个数:

int arr3[ ] ={1,2,3,4,5,6,7,8,9,10};

 编译器会根据初始化内容来确定数组的元素个数。

字符数组:

char arr6[3]={'a','b','c'};
char arr8[]="abc";
//四个元素,还有一个\0

 全局数组和全局变量一样,不初始化的话里面就是0。

1.3一维数组的使用

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

 第一个元素下标为0,第二个元素下标为1,下标从0开始,依次往后涨。

int main( )
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};
    int sz=sizeof(arr)/sizeof(arr[0]);
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);//访问元素,里面可以是变量
    }
    return 0;
}

上述代码就是用 i 的值从0到9,利用 i 来访问下标,依次打印数组的下标。数组有一个非常好的优点,就是在知道下标的前提下,可以随时访问数组中的元素。

总结

1、数组是使用下标来访问的,下标是从0开始的。

2、数组的大小可以通过计算得到

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

我们根据以下代码来打印内存地址:

#include <stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("&arr[%d] = %p\n ", i,&arr[i]);//访问元素,里面可以是变量,打印地址
    }
    return 0;
}

最后运行结果:

这里面十六进制C对应的是12,所以上面地址之间通通差4。

所以可以知道,一维数组在内存中是连续存放的,随着数组下标的增长,地址是由低到高变化的。

 只要我们知道起始位置,就可以访问其余的元素。

#include <stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    int* p=&arr[0];
    for (i = 0; i < sz; i++)
    {
        printf("%d", *(p+i));//访问元素,通过地址来访问元素
    }
    return 0;
}

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

2.1二维数组的创建

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

如上所示,创建整形3行4列名字为arr的二维数组,创建字符类型三行五列名字为arr的二维数组,创建双精度浮点数二行四列名字为arr的二维数组。 

如果给出下列代码,我们该如何理解:

int main( )
{
    int arr[3][4];

    return 0;
}

 这就是三行四列。

 2.2二维数组的初始化

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

    return 0;
}

 给arr这个二维数组中传入元素,如下图:

如果我们这放不满(不完全初始化),只放入12345:

int main( )
{
    int arr[3][4]={1,2,3,4,5};

    return 0;
}

我们如果想要在每行放入不同数字,想要在固定位置放入数字,那么就可以把每行认为成一个一维数组,通过一维数组来规定每一行的数组元素放什么。

int main()
{
    int arr[3][4]={ {1,2},{3,4},{5,6} };
    return 0;
}

上述代码把数据传进去后就是下面这样的: 

 注意:二维数组如果有初始化,行可以省略,列不能省略。

我们想象一下都能想出来,如果不放行的话,那么我们放入数的时候,想放多少就放多少,因为有列,限制了这些数的存放,而列不放入的时候,那么后面该如何放呢,一行该放多少呢。

2.3二维数组的使用

二维数组也是通过下标的方式进行访问数据。

就像下面的代码:

int main( )
{
    int arr4[][2]={1,2,3,4,5,6,7,8,9};
    int i=0;
    for(i = 0; i < 5 ; j++)
    {
        printf("%d",arr4[i][j]);
    }
    printf("\n");
}

这就是通过下标来打印出这个不定义行的二维数组。打印结果如下图:

绿色的是下标,比如1对应的就是 arr4[0][0],以此类推,因为就九个数,所以他最后一个为0。i就是行,j就是列。

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

我们通过定义一个三行四列的二维数据来了解怎么储存的:

#include <stdio.h>
int main()
{
	int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	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;
}

代码执行结果就是:

因为C是12,所以每一个整形之间差了4,我们可以看见每一个地址与地址之间都差4,二维数组好像在内存中也是连续储存的。

我们以为它在内存中是这样的:

但是实际上它是这样的:

假想中是多上多列的,但是在内存中还是连续储存的。 

这时候就可以想到刚才说列为什么不能省略了,如果没有列,那么我们就不知道一行放多少,那么第二行该从什么时候开始放。

我们从上面就可以把这个三行四列的二维数组看成一个有12个元素的一维数组。

当我们访问第一行的元素时,都是arr [ 0 ][ j ],j从0到3;第二行的时候,arr [ 1 ][ j ],j从0到3;第三行的时候,都是arr [ 2 ][ j ],j从0到3。

可以把二维数组想成一维数组,而一维数组中每个元素又是一个一维数组。

3、数组越界

数组的下标是有范围限制的。

数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1,所以数组的下标如果小于0,或者大于n-1,那么就是数组越界访问了,超出了数组合法空间的访问。

C语言本身是不做数组小标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,所以程序员写代码的时候,最好自己做越界的检查。

 

有的时候越界后,编译器并不会出现错误,但是会打印出来随机值,因为我们知道打印出来随机值就可能是越界访问了。

如果出现一个弹窗,弹窗说-Stack around the variable 'arr' was corrupted.那么就果断的判断它是越界了。类似这样的都是越界,就应该回去检查写出来的代码。


总结

本篇文章讲解了一维数组和二维数组的初始化以及使用,还有一些储存的方式,个人感觉数组还是非常重要的,大家可以多多练习。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

时空智友企业流程化管控系统uploadStudioFile接口存在任意文件上传漏洞

免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 时空智友…

【Vulnhub靶场】Kioptrix Level 3

目标 本机IP&#xff1a;192.168.118.128 目标IP&#xff1a;192.168.118.0/24 信息收集 常规 nmap 扫存活主机&#xff0c;扫端口 根据靶机IP容易得出靶机IP为 192.168.118.133 nmap -sP 192.168.118.0/24nmap -p- 192.168.118.133 Getshell 开放22端口和80 端口 访问web…

C++进阶之路:日期类的实现、const成员(类与对象_中篇)

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

如何选择合适的云服务商,看IDC怎么说

01 | 2份IDC报告&#xff0c;评估了Covid后的云增长与云服务市场的变化 《IDC MarketScape&#xff1a;全球公有云基础设施即服务提供商评估》&#xff08;2022&#xff09;共评估了 13 家云提供商&#xff0c;其中既有超大规模云服务商&#xff0c;如亚马逊云科技&#xff1b…

论文阅读-三维结构几何修复(导-4)

摘要 解决了3D数字模型中大洞修复的问题。 通过基于字典学习的方法解决了缺失区域推断问题&#xff0c;该方法利用从单个自相似结构和在线深度数据库中得出的几何先验。利用几何先验提供的线索&#xff0c;从洞的边界周围自适应地传播局部3D表面平滑性来恢复底层表面。在合成…

word中的内容旋转90度

在vsto、Aspose.Words 中&#xff0c;默认没有直接的 API 可以让表格整体旋转 90 度。然而&#xff0c;我们可以通过一些方式来实现类似的效果&#xff0c;具体思路如下&#xff1a; 将表格插入到一个形状&#xff08;Shape&#xff09;或文本框中&#xff0c;然后旋转该形状。…

使用Docker启动的Redis容器使用的配置文件路径等问题以及Python使用clickhouse_driver操作clickhouse数据库

一、使用Docker启动的Redis容器使用的配置文件路径等问题 1.docker启动的redis使用的配置文件路径是什么 使用docker搭建redis服务&#xff0c;本身redis启动的时候可以指定配置文件的&#xff0c; redis-server /指定配置文件路径/redis.conf。 但手上也没有一个redis配置文件…

【Golang】合理运用泛型,简化开发流程

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

灵动AI视频最新AIGC 系统:支持多种模型切换 支持5端部署

灵动AI视频官网地址&#xff1a;https://aigc.genceai.com/

SeCo复现

表1 复现结果–CAM&#xff1a;74.751 Mask&#xff1a;76.47 Val&#xff1a;74.0 Test&#xff1a;73.7948&#xff0c;完全一致 表3 复现结果&#xff1a;0.233&#xff0c;完全一致 感想 第10篇完全复现的论文

知识点框架笔记3.0笔记

如果基础太差&#xff0c;搞不清基本交规的&#xff08;模考做不到60分&#xff09;&#xff0c;建议找肖肖或者小轩老师的课程看一遍&#xff0c;内容差不多&#xff08;上面有链接&#xff09;&#xff0c;笔记是基于肖肖和小轩老师的科目一课程以及公安部交管局法规&#xf…

京东笔试题

和谐敏感词 &#x1f517; 题目地址 &#x1f389; 模拟 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();String s scanner.next();String[] words new String[…

Android GPU Inspector分析帧数据快速入门

使用 谷歌官方工具Android GPU Inspector (AGI) 可以对Android 应用进行深入和全面的系统性能分析和帧性能分析 。AGI 是一个非常强大的分析工具&#xff0c;尤其是在需要诊断 GPU 性能问题和优化应用时&#xff0c;可以帮助你精准找到性能瓶颈。本文介绍如何使用该工具对帧数据…

Docker 安装Postgres和PostGIS,并制作镜像

1. 查找postgres和postgis现有的镜像和版本号 镜像搜索网站&#xff1a;https://docker.aityp.com/ 测试使用的是postgres:15.4 和 postgis:15-3.4 2、镜像拉取 docker pull postgres:15.4docker pull postgis/postgis:15-3.4镜像下载完成&#xff0c;docker images 查看如…

CentOS7安装RabbitMQ-3.13.7、修改端口号

本文安装版本&#xff1a; Erlang&#xff1a;26.0 官网下载地址 Erlang RabbitMQ&#xff1a;3.13.7 官网下载地址 RabbitMQ RabbitMQ和Erlang对应关系查看&#xff1a;https://www.rabbitmq.com/which-erlang.html 注&#xff1a;安装erlang之前先安装下依赖文件&#xff0…

【Hive】8-Hive性能优化及Hive3新特性

Hive性能优化及Hive3新特性 Hive表设计优化 Hive查询基本原理 Hive的设计思想是通过元数据解析描述将HDFS上的文件映射成表 基本的查询原理是当用户通过HQL语句对Hive中的表进行复杂数据处理和计算时&#xff0c;默认将其转换为分布式计算 MapReduce程序对HDFS中的数据进行…

软件测试学习笔记丨Linux三剑客-sed

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/32521 一、简介 sed&#xff08;Stream editor&#xff09;是一个功能强大的文本流编辑器&#xff0c;主要用于对文本进行处理和转换。它适用于自动化处理大量的文本数据&#xff0c;能够支持…

九、pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover&#xff08;悬停&#xff09; 定义&#xff1a;发起交互的对象停留在可交互对象的交互区域。例如&#xff0c;当手触摸到物品表面&#xff08;可交互区域&#xff09;时&#xff0c;视为触发了Hover。 Grab&#xff08;抓取&#xff09; 概念&#xff…

记录一个容易混淆的 Spring Boot 项目配置文件问题

记录一个容易混淆的 Spring Boot 项目配置文件问题 去年&#xff0c;我遇到了这样一个问题&#xff1a; 在这个例子中&#xff0c;由于密码 password 以 0 开头&#xff0c;当它被 Spring Boot 的 bean 读取时&#xff0c;前导的 0 被自动去掉了。这导致程序无法正确读取密码。…

【Next.js 项目实战系列】07-分配 Issue 给用户

原文链接 CSDN 的排版/样式可能有问题&#xff0c;去我的博客查看原文系列吧&#xff0c;觉得有用的话&#xff0c;给我的库点个star&#xff0c;关注一下吧 上一篇【Next.js 项目实战系列】06-身份验证 分配 Issue 给用户 本节代码链接 Select Button​ # /app/issues/[i…