掘根宝典之c语言一维数组

2024-03-02 19:44

本文主要是介绍掘根宝典之c语言一维数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是数组

数组是一种存储固定大小的相同类型元素的数据结构。

数组可以包含任意类型的元素,例如整数、浮点数、字符等。在内存中,数组通常是连续存储的,每个元素按照一定的间隔存储。

通过使用数组,可以有效地存储和访问一系列相同类型的数据。数组可以用于各种场景,例如存储学生的成绩、保存图像像素值等。

在C语言中,数组是一种重要的数据结构,并且具有高效的访问和操作特性。使用数组可以提高代码的可读性和可维护性。

一维数组

一维数组是指只有一个维度的数组,通常是一列或一行的数据元素组成。一维数组中的每个元素可以通过一个唯一的索引来访问。例如,一个包含5个整数的一维数组可以表示为 [1, 2, 3, 4, 5]。在许多编程语言中,一维数组可以通过定义一个变量名称和方括号([])来表示。

声明

C语言中的一维数组的声明方式为:

类型 数组名[大小];

其中,类型表示数组元素的数据类型,数组名表示数组的名称,大小表示数组中元素的个数。

例如,声明一个包含5个整数的数组:

int numbers[5];

指定数组大小

需要注意的是,数组的大小是固定的,声明后不能改变

如果需要动态的大小,可以使用指针和动态内存分配。 

数组大小只能用整型常量(strlen()和sizeof()的返回值被视为整型常量,const int在C语言不是整型常量,但是在C++是)或者整型常量表达式

#define we 10
int a[we];
int b[sizeof(int)];
int d[3+4];const int h=10;
int c[h];
//这在c语言是不可以的,但是在C++中是可以的

 如果不确定数组的大小,可以使用省略号来让编译器根据初始化列表的项数自动推断数组大小:

int arr[] = {1, 2, 3, 4}; // 编译器会自动推断数组大小为4

 

初始化

在C语言中,一维数组的初始化可以通过以下几种方式实现:

逐个赋值:

使用循环或直接为每个元素赋值的方式进行初始化。例如,我们可以使用以下方式初始化一个整数数组:

int arr[5];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;

使用大括号初始化列表:

可以使用大括号来直接为数组赋初值,元素之间用逗号分隔。例如,我们可以使用以下方式初始化一个整数数组:

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

这种方式可以在数组创建的同时完成初始化,更加简洁。

部分初始化:

可以只为数组的某些位置指定初始值,其余位置将自动赋值为0。例如,我们可以使用以下方式初始化一个整数数组:

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

这样,数组的前两个元素分别为1和2,后三个元素自动赋值为0。

指定初始化

这个特性可能在某些编译器上不支持(比如VS2022)

C语言中,可以使用指定初始化器来为数组的指定位置赋初值,其余位置将自动赋值为0。
指定初始化器的语法是在大括号中指定每个元素的值,并用逗号分隔。

例如,我们可以使用指定初始化器来初始化个长度为5的整数数组

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

上面的代码中,数组的前两个元素分别为1和2,第三个元素为3,第四个元素为4,而第五个元素将自动赋值为0。
你可以根据需要选择性地指定初始化器来初始化数组的指定位置,而不必为每个元素都提供初值。这样可以使代码更加清晰和简洁,

无论使用哪种方式,只要保证赋值的元素个数和数组的长度一致即可完成初始化。

注意

如果在数组初始化时,会发生以下情况:

  1. 如果初始化列表的项数小于数组元素个数,则多余的元素会被自动初始化为0。
int arr[5] = {1, 2, 3}; // arr[3]和arr[4]会被初始化为0

  1. 如果初始化列表的项数大于数组元素个数,则会导致编译错误。
int arr[3] = {1, 2, 3, 4}; // 编译错误,初始化列表的项数超过了数组元素个数

因此,要确保初始化列表的项数与数组元素个数相匹配,以避免潜在的错误。
 

访问

C 语言中,数组通常是顺序存储的,在内存中按照连续的地址存储。

这意味着数组的元素是紧密排列的,可以通过指针和索引进行高效的访问

可以通过下标来访问数组中的元素,下标从0开始

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

例如,访问数组中的第一个元素:

a[0];//对应第一个元素
a[2];//对应第三个元素
a[4];//对应第四个元素

数组越界

在 C 语言中,数组的越界访问是一种错误的行为,指的是访问数组的索引超出了数组的有效范围。

这种行为是未定义的,会导致程序的不可预测行为,并且可能引发诸如程序崩溃、数据损坏、安全漏洞等问题。

例如,如果一个数组的大小为5,有效的索引范围是0到4。如果访问超出范围的索引,就会发生越界访问错误。

int arr[5] = {1, 2, 3, 4, 5};
int x = arr[10];  // 越界访问错误,arr 的有效索引范围是 0 到 4

为了避免越界访问错误,应该始终确保数组的索引在有效范围内。在编写代码时,应该特别注意循环和指针操作,以确保不会出现数组越界访问。

注意事项

1.声明数组时,[]内不能使用变量(但是可以定义变长数组)

也就是说,下面这种情况是不允许的

int a=9;
int b[a];

2.创建数组时既不给数组指定大小,也不初始化是不对的

int b[];//这是不对的

3.在创建数组时初始化数组

我们在创建数组时就应该养成初始化数组的习惯,

如果你想后面再对其进行赋值,那可以先将数组的值全设置为0;就像下面这么做

int b[10]={0};

4.不能把一个数组赋给另一个数组,可以把数组赋给指针 

下面这种操作是不行的

int a[2] = { 3 };
int b[2] = a[2];

下面这种操作是可以的

	int a[2] = { 3 };int* b = a;

 

数组名的意义

在 C 语言中,数组名表示数组的首地址。它是一个常量指针,指向数组中第一个元素的地址。

我们可以举个例子

int a[10];
int* const b=&a[0];

这样子数组名a和指针b几乎是一样的了 ,即b不能改变但是可以改变*b

数组名的意义主要体现在以下几个方面:

  1. 访问数组元素:可以使用数组名和索引来访问数组中的元素。例如,对于数组 int arr[5] = {1, 2, 3, 4, 5};,可以使用 arr[0]arr[1] 等来访问数组中的元素。

  2. 数组作为函数参数:当数组作为函数参数传递时,实际上传递的是数组的地址。因此,函数内部可以通过数组名来访问和修改数组的元素,对数组的修改会影响到原始数组。

  3. 指针运算:数组名可以被视为指向数组首元素的指针。因此,可以使用指针运算来处理数组。例如,arr + 1 表示数组第二个元素的地址,*(arr + 2) 表示数组第三个元素的值。

  4. 数组大小:使用 sizeof 运算符可以获取数组的大小。例如,sizeof(arr) 返回整个数组的大小(字节数),可以根据数组大小来进行内存分配和操作。

总之,数组名在 C 语言中具有指向数组首地址、访问数组元素、作为函数参数和指针运算等重要作用。它是与数组相关的重要概念之一。

指针创建一维数组

指针可以用来创建一维数组。创建一维数组的过程通常包括以下步骤:

  1. 声明指向数据类型的指针变量。
  2. 使用动态内存分配函数(例如malloc)为数组分配内存空间。
  3. 对数组进行赋值和操作。
  4. 使用完数组后,使用free函数释放内存空间。

下面是一个示例,展示如何使用指针创建一维数组:

#include <stdio.h>
#include <stdlib.h>int main() {int size;printf("Enter the size of the array: ");scanf("%d", &size);// 动态分配内存空间int* arr = (int*)malloc(sizeof(int) * size);// 检查内存分配是否成功if (arr == NULL) {printf("Memory allocation failed.\n");return 1;}printf("Enter the elements of the array:\n");for (int i = 0; i < size; i++) {scanf("%d", &arr[i]);}printf("The elements of the array are: ");for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");// 释放内存空间free(arr);return 0;
}

在上述示例中,首先要求用户输入数组的大小。然后使用malloc函数为数组分配大小为size的内存空间。接下来,使用循环从用户获取数组的元素值,并打印出数组的元素。最后,使用free函数释放数组的内存空间。

请注意,在使用完数组后,务必记得释放动态分配的内存空间,以防止内存泄漏。

一维数组传参

一维数组可以作为函数参数传递给函数。在函数定义中,可以声明一个接收一维数组的形参,并在函数调用时将数组作为实参传递给该函数。

那我们怎么设计这个函数接口呢?

我们先以传下面这个数组为例

int a[10];

 我们要知道数组名代表数组首元素的地址,所以在设计参数时,我们不仅可以用数组形式表示,还可以用指针形式表示

所以以下四种函数接口设计都是等价的

int sum(int*ar);
int sum(int*);
int sum(int ar[]);
int sum(int []):

但是在函数定义中不能省略参数名,所以以下这两种函数函数定义等价

int sum(int*ar)
{
}
int sum(int ar[])
{
}

这篇关于掘根宝典之c语言一维数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/767224

相关文章

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件