做问卷不花钱的网站,怎么自己制作app,做一个网页难不难,西宁网站建设优化#x1f4dd;个人主页#x1f339;#xff1a;Eternity._ ⏩收录专栏⏪#xff1a;C语言 “ 登神长阶 ” #x1f921;往期回顾#x1f921;#xff1a;C语言函数 #x1f339;#x1f339;期待您的关注 #x1f339;#x1f339; ❀数组 #x1f4d2;1. 什么是数组… 个人主页Eternity._ ⏩收录专栏⏪C语言 “ 登神长阶 ” 往期回顾C语言函数 期待您的关注 ❀数组 1. 什么是数组数组的特点数组的应用 2. 一维数组数组的创建数组的初始化数组的使用⭐数组在内存中的存储 3. 二维数组数组的创建数组的初始化数组的使用⭐数组在内存中的存储 4. 数组越界5. 数组作为函数参数⛰️数组作为函数参数错误设计️数组名正确设计 6. 总结 前言 在编程的世界里数据结构是构建复杂应用程序的基石而数组则是这些基石中最基础且最不可或缺的一种。C语言作为一门历史悠久且广泛应用于系统编程、嵌入式开发等领域的编程语言其数组的概念与操作更是每一位C语言学习者必须掌握的核心技能 数组简而言之是一种连续存储相同类型数据的集合。它允许我们通过索引或下标快速访问其中的元素无论是读取还是修改都极为高效。C语言中的数组不仅支持一维形式还可以轻松扩展到多维为处理复杂数据提供了极大的便利 本文旨在全面而深入地介绍C语言数组的基本概念、声明与初始化、访问与遍历、以及多维数组的应用等关键内容。通过理论讲解与实例演示相结合的方式我们将逐步揭开C语言数组的神秘面纱帮助读者建立扎实的数组知识基础并掌握在实际编程中灵活应用数组的技巧
让我们一同踏上这段充满挑战与收获的C语言数组之旅吧 1. 什么是数组 数组Array是一种基础的数据结构用于在计算机内存中连续存储相同类型的数据。它允许通过索引或下标来访问这些数据元素索引通常是从0开始的。数组中的每个元素可以通过计算偏移量来快速定位这使得数组在访问元素时非常高效 数组的特点 类型一致性 数组中的所有元素都必须是相同的数据类型。这意味着如果你有一个整型数组那么数组中的所有元素都必须是整数固定大小 在大多数编程语言中数组的大小在声明时就必须确定并且之后不能改变尽管有些语言支持动态数组或类似的数据结构如C的std::vector或Python的列表它们提供了动态大小的数组功能。然而在C99标准中C语言引入了变长数组VLA其大小可以在运行时确定但这仍然受到栈大小等限制索引访问 数组中的元素可以通过索引来访问索引通常是从0开始的。例如在C语言中如果你有一个名为arr的数组并且你想要访问它的第一个元素你可以使用arr[0]内存连续性 数组中的元素在内存中是连续存储的。这意味着如果你知道数组中某个元素的地址你可以很容易地计算出数组中其他元素的地址 数组的应用 存储和处理一系列的数据如学生的成绩、商品的库存量等作为函数参数传递数据集合实现算法如排序、搜索等字符串处理因为字符串在C语言中是通过字符数组来实现的表示多维数据结构如矩阵和表格 尽管数组是编程中非常基础且强大的工具但它们也有一些局限性比如大小固定对于传统数组而言和类型单一。因此在需要更灵活的数据结构时程序员可能会选择使用其他数据结构如链表、树或图等。然而对于许多常见的编程任务来说数组仍然是首选的数据结构之一 2. 一维数组 数组是一组相同类型元素的集合 数组的创建
数组的创建方式
type_t arr_name [const_n];
// type_t 是指数组的元素类型
// const_n 是一个常量表达式用来指定数组的大小数组创建代码示例 (C语言)
//代码1
int arr1[10];//代码2
int count 10;
int arr2[count];//代码3
char arr3[10];
float arr4[1];
double arr5[20];注意我们来看一下代码二数组创建在C99标准之前 [ ] 中要给一个常量才可以不能使用变量。在C99标准支持了变长数组的概念数组的大小可以使用变量指定但是数组不能初始化 数组的初始化 数组的初始化是指在创建数组的同时给数组的内容一些合理初始值初始化 数组的初始化
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 };数组的使用 对于数组的使用我们之前介绍了一个操作符 [] 下标引用操作符。它其实就数组访问的操作符 数组的使用
int main()
{int arr[10] { 0 };//数组的不完全初始化//计算数组的元素个数int sz sizeof(arr) / sizeof(arr[0]);//对数组内容赋值,数组是使用下标来访问的下标从0开始。所以int i 0;//做下标// for循环遍历数组for (i 0; i sz; i){arr[i] i;}//输出数组的内容i 0;// while循环遍历数组while (i sz){printf(%d , arr[i]);i;}return 0;
}通过示例 数组是使用下标来访问的下标是从0开始数组的大小可以通过计算得到 int arr[10];
int sz sizeof(arr)/sizeof(arr[0]);⭐数组在内存中的存储
代码示例 (C语言)
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;
}注意仔细观察输出的结果我们知道随着数组下标的增长元素的地址也在有规律的递增 由此可以得出结论数组在内存中是连续存放的 3. 二维数组 二维数组也称为矩阵是计算机科学中常用的数据结构用于存储具有两个维度的数据集合。简单来说它是一个数组的数组即每个元素本身也是一个数组。二维数组在图像处理、游戏开发、数据分析、科学计算等领域有广泛应用 数组的创建
数组的创建方式
type_t arr_name [const_n][const_m];
// type_t 是指数组的元素类型
// const_n 表示行的大小
// const_m 表示列的大小//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];数组的初始化
数组的初始化方式
//数组初始化
int arr[3][4] {1,2,3,4};
int arr[3][4] {{1,2},{4,5}};
int arr[][4] {{2,3},{4,5}};
// 二维数组如果有初始化行可以省略列不能省略数组的使用
二维数组的使用也是通过下标的方式
数组的遍历
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]);}printf(\n);}return 0;
}⭐数组在内存中的存储
我们来打印以下二维数组的地址看看
内存中的存储
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;
}我们可以看出来其实二维数组在内存中也是连续存储的 4. 数组越界 数组越界Array Bounds Violation 或 Index Out of Bounds是编程中常见的一个错误主要发生在尝试访问数组时使用的索引超出了数组的有效范围。在大多数编程语言中数组索引是从0开始的因此对于一个长度为n的数组有效的索引范围是0到n-1。如果尝试访问索引为n或更大的元素就会发生数组越界错误 数组的下标是有范围限制的 数组的下规定是从0开始的如果数组有n个元素最后一个元素的下标就是n-1 所以数组的下标如果小于0或者大于n-1就是数组越界访问了超出了数组合法空间的访问。C语言本身是不做数组下标的越界检查编译器也不一定报错但是编译器不报错并不意味着程序就是正确的 所以程序员写代码时最好自己做越界的检查
数组越界
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;
}注意二维数组的行和列也可能存在越界 数组越界的影响 程序崩溃 在许多编程语言中如C/C、Java数组越界通常会导致程序崩溃或抛出异常因为系统不允许访问未分配的内存区域。数据损坏 在某些情况下如果数组越界没有被系统捕获可能会覆盖或损坏内存中的其他数据导致难以跟踪的错误。安全漏洞 在安全敏感的应用程序中数组越界可能被恶意用户利用来执行未授权的操作或访问敏感数据 5. 数组作为函数参数 数组作为函数参数在C或C等编程语言中是一个常见的操作。然而当数组作为函数参数传递时它并不直接传递整个数组的内容而是传递了数组的首地址即数组第一个元素的地址。这意味着函数内部对数组的任何非本地即不在函数内部定义的修改都会影响到原始数组 ⛰️数组作为函数参数错误设计
代码示例 (C语言)
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);//是否可以正常排序for (int i 0; i sizeof(arr) / sizeof(arr[0]); i){printf(%d , arr[i]);}return 0;
}此处冒泡排序并不能发挥作用 注意数组作为函数参数的时候并不是把整个数组的传递过去而是传的是首元素的地址 ️数组名
数组名的含义代码示例 (C语言)
int main()
{int arr[10] { 1,2,3,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
两个例外 sizeof(数组名)计算整个数组的大小sizeof内部单独放一个数组名数组名表示整个数组数组名取出的是数组的地址。数组名数组名表示整个数组 正确设计
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{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};int sz sizeof(arr)/sizeof(arr[0]);// 我们先计算好数组的大小bubble_sort(arr, sz);for(int i0; i sz; i){printf(%d , arr[i]);}return 0;
}6. 总结
在探索C语言数组的旅程即将结束之际我们不禁要回顾这一路上所见的风景与收获。数组作为C语言乃至众多编程语言中的基石之一其重要性不言而喻。它不仅是我们存储和操作一系列相同类型数据的高效工具更是构建复杂数据结构如矩阵、字符串等的基础 通过本文的介绍我们深入了解了C语言数组的定义、初始化、访问以及通过循环遍历数组的方法。我们见证了数组如何帮助解决一系列实际问题从简单的数学计算到复杂的数据处理数组都以其独特的方式展现出了其强大的功能性和灵活性 然而正如任何强大的工具一样数组的使用也需要谨慎。越界访问、内存泄漏等问题是我们在使用数组时不得不面对的挑战。因此掌握良好的编程习惯如在使用前检查数组边界、合理管理内存等对于避免潜在的问题至关重要
让我们在掌握C语言函数的基础上继续保持对编程的热情与好奇心勇于探索未知不断挑战自我 希望本文能够为你提供有益的参考和启示让我们一起在编程的道路上不断前行 谢谢大家支持本篇到这里就结束了祝大家天天开心