【C语言初阶】带你玩转C语言中的数组,并逐步实现冒泡排序,三子棋,扫雷 1

简介: 【C语言初阶】带你玩转C语言中的数组,并逐步实现冒泡排序,三子棋,扫雷

前言

Hello,这里是君兮_,今天为大家带来的是在C语言对数组的详解,废话不多说我们直接开始吧!


一维数组

1.一维数组的定义

C语言中给了数组的定义:一组相同类型元素的集合

数组的创建:

type_t arr_name [const_n];

type_t 是指数组的元素类型

const_n 是一个常量表达式,用来指定数组的大小


我们有时可能会看到这种数组:

int count = 10;
int arr2[count];//数组时候可以正常创建吗?

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

简单来说就是要看你的编译器,为了防止写出bug,我建议一般创建数组是还是不要这么写了。

数组的分类

根据元素类型的不同,数组大致可以分为三类:

整型数组

                         

                               int arr1[10]

字符数组

                              char arr2[10]

浮点型数组

                       

                            double arr3[10]

2.数组的初始化

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

话不多说,直接看代码:

int arr1[10] = {1,2,3,4,5,6,7,8,9,10};//完全初始化
int arr2[10] = { 1,2,3 };//不完全初始化,剩余的元素默认都是0
int arr3[10] = { 0 };//不完全初始化,剩余的元素默认都是0
int arr4[] = { 0 };//省略数组的大小,数组必须初始化,数组的大小是根据初始化的内容来确定
char arr5[] = {'a','b','c'};
char arr6[] = "abcdef";
char arr7[]={"abcdef"}//与arr6一个意思,arr6是它的缩写

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

第一种越界情况

但是对于下面的代码要区分,内存中如何分配

int main()
{
  char arr1[] = {"abc"};
  char arr2[] = {'a','b','c'};
  printf("%s\n",arr1);
  printf("%s", arr2);
}

代码结果如图:

b9d83fbbd5c848da896ecf24977e3177.png

为啥会出现这种情况?

注意:当我们以%s形式打印上面数组内容时,遇到’\0’才会停止。第一个数组中的“abc”是一个字符串,在后面有一个我们看不见的’\0’,而第二个数组中是三个字符‘a’ ‘b’ ‘c’,后面是没有’\0’的,此时我想告诉你的是,你的第二个数组越界了!!此时这个数组后面存放的是随机值,打印出来就是随机的乱码,而直至它越界访问的地方出现0即’\0’,才会停止打印。

证明一下:

23a6a16c28ee47c1b915608326f0e57e.png

说明我们上面的说法是没错的。

3.数组的使用

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

数组的下标:

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

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


int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);//用整个数组的大小除以第一个元素的大小得到的就是数组中元素的个数

第二种越界情况

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

数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。

所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。

C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,

代码如下:


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;
}

这样改可以吗?

for (i = 0; i <=10; i++)

改完结果:

239ad80b7fe54af3b97e62f66140680b.png

这里连编译都走不过去,为什么?

越界访问!

注意:

1 当你写完上面的代码后,我想问问你,你的数组初始化时有几个元素呢?

int arr[10] = { 0 };//最多10个

2 数组的下标是从0开始的,也就是说最后一个元素的下标应该是9,即arr[9]。

3 当你把i的条件改为i<=10后,你会惊奇的发现,你的下标竟然能出现arr[10]!你数组里根本没有这个元素,这不是又越界吗了?

总结:

切记切记,上面两种越界情况是经常出现的,尤其是第二种。

我们经常在循环时因条件设置有误而导致越界,当代码多了之后,这种错误是非常难以发现的。我费这么大篇幅讲这两种越界情况就是为了提醒你们在以后使用数组的时候一定要小心谨慎,要多考虑考虑是否会出现越界情况,避免一个bug要找半天(博主的切身经历)

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;
}


d31fe5f264ea4e0e8a9dc831b7eea128.png


由于该数组为int型数组,每个元素占四个字节,即每一元素地址对应+4,实际还是从低地址到高地址连续存放

07f698ad30f243ccb8954d89521991ec.png


仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。

由此可以得出结论:数组在内存中是连续存放的。


目录
相关文章
|
24天前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
78 6
|
28天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
54 5
|
28天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
1月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
1月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
搜索推荐 C语言
【C语言】使用回调函数通过冒泡排序模拟实现qsort函数
【C语言】使用回调函数通过冒泡排序模拟实现qsort函数
【C语言】使用回调函数通过冒泡排序模拟实现qsort函数
|
24天前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
49 10
|
24天前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
43 9
|
24天前
|
存储 Unix Serverless
【C语言】常用函数汇总表
本文总结了C语言中常用的函数,涵盖输入/输出、字符串操作、内存管理、数学运算、时间处理、文件操作及布尔类型等多个方面。每类函数均以表格形式列出其功能和使用示例,便于快速查阅和学习。通过综合示例代码,展示了这些函数的实际应用,帮助读者更好地理解和掌握C语言的基本功能和标准库函数的使用方法。感谢阅读,希望对你有所帮助!
33 8
|
24天前
|
C语言 开发者
【C语言】数学函数详解
在C语言中,数学函数是由标准库 `math.h` 提供的。使用这些函数时,需要包含 `#include <math.h>` 头文件。以下是一些常用的数学函数的详细讲解,包括函数原型、参数说明、返回值说明以及示例代码和表格汇总。
43 6