首页 > 其他分享 >C语言知识大闯关之二维数组与变长数组

C语言知识大闯关之二维数组与变长数组

时间:2024-07-25 21:25:29浏览次数:9  
标签:初始化 arr int 元素 C语言 二维 变长 数组

目录

引言

上一章节我们学习了一维数组,而我们知道数组分为一维数组和多维数组,而多维数组一般比较多见的是二维数组;此外,还有一种特殊的数组—变长数组。本章我们便来学习一下二维数组与变长数组;

1.二维数组的创建

1.1二维数组的概念

在我们学习了一维数组之后,我们知道,数组的元素都是内置的,当我们把一维数组作为数组的元素的时候,所构成的数组就被成为二维数组;二维数组作为元素构成的数组为三维数组;而二维数组以上的数组就叫做多维数组;

在这里插入图片描述

1.2二维数组的创建

那么我们如何创建二维数组呢?

如下示例代码:

// type arr_name[常量值][常量值]

// 例如:

int arr[3][5];
char ch[6][6];
float fl[5][5];

解释一下上述代码出现的信息:

  • 3表示数组有三行
  • 5表示每行有五个元素
  • int表示数组中的元素为整数类型
  • arr是数组名,可以根据自己的需要指定名字;

如一维数组一样 :

  • type 表示数组中存储的元素的类型;
  • arr_name表示数组名称;
  • 第一个[]中的常量值表示二维数组的行,第二个[]中的常量值表示二维数组的列;

2.二维数组的初始化

在创建变量或数组的时候,给定一些初始值,就叫做初始化

那么二维数组是如何初始化的呢?同一维数组一样,也是用大括号进行初始化的;

2.1不完全初始化

int arr1[3][5] = {1 , 2};
int arr2[3][5] = {0};

在这里插入图片描述

2.2完全初始化

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

在这里插入图片描述

2.3按照行初始化

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

在这里插入图片描述

2.4初始化时省略行,但不可以 省略列

int arr5[][5] = {1,2,3};
int arr6[][5] = {1,2,3,4,5,6,7};
int arr7[][5] = {{1,2},{3,4},{5,6}};

在这里插入图片描述

3.数组的使用

3.1二维数组的下标

当我们掌握了二维数组的创建和初始化,那么我们如何使用二维数组呢?

同一维数组一样,二维数组也是有下标的,二维数组是有行和列的,只要锁定了二维数组的行和列,我们就能锁定二维数组中的一个元素;

C语言规定,二维数组行是从0开始的,列是也是从0开始的;如下图所示:

在这里插入图片描述

左边最右侧的绿色数字表示为行号,最上面一侧的蓝色数字表示为列号,比如我们说第二行第四列就能锁定到元素7;

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

输出结果
在这里插入图片描述

3.2二维数组的输入和输出

我们已经知道如何访问二维数组中的一个元素了,那我们如何访问整个数组呢?

其实只要我们生成对应的行数的列数,然后遍历打印就可以了!

以上一段代码中的二维数组为例,行为0 ~ 2,列为0 ~ 4。我们可以通过如下代码来实现!

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

输出结果
在这里插入图片描述

二维数组在内存中的存储

和一维数组一样,我们想要研究二维数组中的元素在内存中的存储,我们需要先打印出数组所有元素的地址的;

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

输出结果

在这里插入图片描述

从输出的结果我们可以得知,每⼀⾏内部的每个元素都是相邻的,地址之间相差4个字节,跨⾏位置处的两个元素(如:arr[0][4]和arr[1][0])之间也是差4个字节,所以⼆维数组中的每个元素都是连续存放的。

在这里插入图片描述

4.C99中的变长数组

在C99标准之前,C语言在创建数组的时候,数组的大小只能由常量,常量表达式;同时如果我们初始化数组的话,可以忽略数组的大小;

int arr1[10];
int arr2[3+5];
int arr3[] = {1,2,3};

这样的语法限制,让我们创建数组不够灵活,有时候数组大了浪费空间,有时候数组小了又不够用

C99中给⼀个变⻓数组(variable-length array,简称 VLA)的新特性,允许我们可以使⽤变量指定数组⼤⼩。

请看以下代码:

int n = a + b;
int arr[n];

上⾯⽰例中,数组 arr 就是变⻓数组,因为它的⻓度取决于变量 n 的值编译器没法事先确定,只有运⾏时才能知道 n 是多少
变⻓数组的根本特征,就是数组⻓度只有运⾏时才能确定,所以变⻓数组不能初始化。它的好处是程序员不必在开发时,随意为数组指定⼀个估计的⻓度,程序可以在运⾏时为数组分配精确的⻓度。有⼀个⽐较迷惑的点,变⻓数组的意思是数组的⼤⼩是可以使⽤变量来指定的,在程序运⾏的时候,根据变量的⼤⼩来指定数组的元素个数,⽽不是说数组的⼤⼩是可变的。数组的⼤⼩⼀旦确定就不能再变化了。
遗憾的是在VS2022上,虽然⽀持⼤部分C99的语法,没有⽀持C99中的变⻓数组,没法测试;

#include <stdio.h>
int main()
{
   int n = 0;
   scanf("%d", &n);//根据输⼊数值确定数组的⼤⼩
   int arr[n];
   int i = 0;
   for (i = 0; i < n; i++)
   {
       scanf("%d", &arr[i]);
   }
   for (i = 0; i < n; i++)
   {
       printf("%d ", arr[i]);
   }
   return 0;
}

在gcc编译器上输出结果

在这里插入图片描述

标签:初始化,arr,int,元素,C语言,二维,变长,数组
From: https://blog.csdn.net/2401_82489659/article/details/140653728

相关文章

  • C语言分支语句之if的一些用法
    目录引言C语言结构1.if语句1.1if1.2else2.分支中包含多条语句3.多重选择elseif4.嵌套if5.悬空else/else与if配对问题引言C语言作为一种非常常用的编程语言,具有灵活强大的循环和分支结构。循环结构允许我们重复执行一段代码,而分支结构则允许我们根据条......
  • 麻了,麻了,终于知道c语言为啥那么容易从入门到放弃了
    麻了,麻了,这谁看不迷糊。(温馨提示:出题时程序一般不会将每一种情况列出,会选其中一个或多个;请勿以答案相同认为思路相同)见了这种题怎么办?猜?这多少分之一的概率?死记?它变个数字又不同了,那得记多少?放弃?好像只能这样了。(不行,不行)今天,博主来教你们彻底解决这些问题。众所周知整......
  • 嵌入式学习第9天——C语言运算符,程序设计结构,输入输出缓冲机制
    2024.7.25第九天笔记关于++混合操作,不同计算结果推理第一种编译结果:inti=5;intsum=(++i)+(++i)=6+7=13第二种编译结果:inti=5;intsum=(++i)+(++i)=6+7=7+7前面的7是因为后面i的变化被影响后,重新赋值=14第一种编译结果:inti=5;in......
  • C语言i++和++i操作
    关于++混合操作,不同计算结果推理第一种编译结果:inti=5;intsum=(++i)+(++i)=6+7=13第二种编译结果:inti=5;intsum=(++i)+(++i)=6+7=7+7前面的7是因为后面i的变化被影响后,重新赋值=14第一种编译结果:inti=5;intsum=(++i)+(i++)=......
  • 学懂C语言(二十五):深入理解 C语言结构体 位域 的概念
            目录一、位域的基本概念二、位域的定义三、位域的内存分配和大小计算示例1:简单位域示例2:跨越多个存储单元注意事项结构体对齐控制总结        C语言中的位域(Bit-Field)是一种特殊的数据结构,允许在结构体中定义占用特定位数的成员,主要用于节......
  • JavaScript(数组)
    今天学习了数组,最为重要的就是数组方法,其次就是遍历,这在作业中用的是最多的。学完发现用数组方法完成作业,比用循环写代码量要少很多。作业1:定义一个数组[1,5,6,99,5,66,7,4,1,6,9]去掉数组里面的重复值(两种方法)第二种方法因为set不明白所以打了注释(借鉴了......
  • C语言:字符串函数、内存函数剖析
    字符串函数、内存函数剖析一、字符串函数(一)求字符串长度1、strlen(1)库函数实现(2)自定义实现(二)长度不受限制的字符串函数1、strcpy(1)库函数实现(2)自定义实现2、strcat(1)库函数实现(2)自定义实现3、strcmp(1)库函数实现(2)自定义实现(三)长度受限制的字符串函数介绍1、strncpy2、s......
  • js中 数组和Object的keys(),values()和entries()方法
    ES6提供三个新的方法——entries(),keys()和values()。它们都返回一个遍历器对象,可以用for…of循环进行遍历,区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历.1.数组的keys()和values()还有entries()方法letarr=['a','b','c']for(let......
  • 随记0000——从0、1 到 C语言
    C语言的发展历程是计算机科学史上的一个重要里程碑。下面是从最早的机器语言到汇编语言,再到高级语言如C语言的简化演进过程:1.机器语言定义与特点机器语言是最底层的编程语言,由一系列二进制代码组成。直接被CPU执行,无需转换或编译。难以阅读、编写和维护。2.汇编语......
  • 数据结构-2. 动态数组1
    动态数组设计structdynamicArray{ void**pAddr;//维护真实在堆区创建的数组的指针 intm_capacity;//数组容量 intm_size;//数组大小};数组初始化structdynamicArray*init_DynamicArry(intcapacity){ if(capacity<=0) { returnNULL; } //给数......