C语言【数组】从入门到精通

简介: C语言【数组】从入门到精通

🐷数组


C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。

数组的声明并不是声明一个个单独的变量,比如 runoob0、runoob1、…、runoob99,而是声明一个数组变量,比如 runoob,然后使用 runoob[0]、runoob[1]、…、runoob[99] 来代表一个个单独的变量。

所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。



数组中的特定元素可以通过索引访问,第一个索引值为 0。




🐸1.一维数组的创建与初始化


🐺数组的创建:


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


格式:type_t arr_name [const_n]


//格式:type_t  arr_name[const_n];
  //type_t  是指数组元素类型
  //const_n  是一个常量表达式,用来指定数组的大小


int main() 
{
  //创建一个数组-存放十个整型-数据
  int arr[10] = {1,2,3,5};//不完全初始化,剩下的元素默认初始化为0
  char ch[5] = {'a','b'};
  char ch1[5] = "ab";
  char ch2[] = "abcdef";//未指定数组大小,必须进行初始化,他会根据初始化内容给数组指定大小
  printf("%d\n", sizeof(ch2));//7
  //size 计算ch2所占空间的大小
  printf("%d\n", strlen(ch2));//6
  //strlen 求字符串长度 遇到\0停止  ,且\0不计入字符串长度
  return 0
  }


注:


1.strlen和sizeof没有什么关联

2.strlen 是求字符串长度的-只能针对于字符长长度 - 库函数 -使用得引头文件

3.sizeof 计算变量,数组,类型的大小 - 单位是字节 - 操作符


初始化 时:大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。如果您省略掉了数组的大小,数组的大小则为初始化时元素的个数。

🐶2.一维数组的使用


对于数组的使用,操作符: [ ] ,下标引用操作符,间接访问数组的操作符。


🦮一维数组的定义


一维数组的定义方式

在C语言中使用数组必须先进行定义。一维数组的定义方式为:


类型说明符 数组名 [常量表达式];


其中,类型说明符是任一种基本数据类型或构造数据类型。数组名是用户定义的数组标识符。方括号中的常量表达式表示数据元素的个数,也称为数组的长度。例如:


int a[10];  /* 说明整型数组a,有10个元素 */
float b[10], c[20];  /* 说明实型数组b,有10个元素,实型数组c,有20个元素 */
char ch[20];  /* 说明字符数组ch,有20个元素 */


对于数组类型说明应注意以下几点:


数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。

数组名的书写规则应符合标识符的书写规定。

数组名不能与其它变量名相同。

方括号中常量表达式表示数组元素的个数,如a[5]表示数组a有5个元素。但是其下标从0开始计算。因此5个元素分别为a[0], a[1], a[2], a[3], a[4]。

不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。

允许在同一个类型说明中,说明多个数组和多个变量。


🐟一维数组的引用


数组元素是组成数组的基本单元。数组元素也是一种变量, 其标识方法为数组名后跟一个下标。下标表示了元素在数组中的顺序号。数组元素的一般形式为:

数组名[下标]

其中下标只能为整型常量或整型表达式。


数组元素通常也称为下标变量。必须先定义数组,才能使用下标变量。在C语言中只能逐个地使用下标变量,而不能一次引用整个数组。


打印数组,下标访问:



总结:


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

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


int sz = sizeof(arr)/sizeof(arr[0]);


🦖3.一维数组在内存中的储存


先看代码:


int main()
{
  int arr[] = { 1,2,3,4,5,6,7,8,9,0};
  int sz = sizeof(arr)/sizeof(arr[0]);
  for (int i = 0; i < sz; i++) {
  printf("&arr[%d]=%p\n",i, &arr[i]);//打印地址用%p
  }
  return 0;
}

上面的数据类型是int型,一个数据在内存中开辟4个字节,又因为16进制是由1,2,3,4,5,6,7,8,9,a,b,c,d,e,f组成

由此不难看出,随着数组下标的增长,元素的地址,也在有规律的变化,因此得出==数组在内存中是连续存放的==


🐇4.二维数组的创建


数组创建:

二维数组定义的一般形式是:


dataType arrayName [length1][length2];


其中,dataType 为数据类型,arrayName 为数组名,length1 为第一维下标的长度,length2 为第二维下标的长度。

我们可以将二维数组看做一个 Excel 表格,有行有列,length1 表示行数,length2 表示列数,要在二维数组中定位某个元素,必须同时指明行和列。


 

int arr1[3][4];//三行四列
  char arr2[3][5];
  double arr3[3][4];


例,arr1定义了一个 3 行 4 列的二维数组,共有 3×4=12 个元素,数组名为 arr1,即:


a[0][0], a[0][1], a[0][2], a[0][3]

a[1][0], a[1][1], a[1][2], a[1][3]

a[2][0], a[2][1], a[2][2], a[2][3]


在C语言中,二维数组是按行排列的。也就是先存放 a[0] 行,再存放 a[1] 行,最后存放 a[2] 行;每行中的 4 个元素也是依次存放。数组 arr1 为 int 类型,每个元素占用 4 个字节,整个数组共占用 4×(3×4)=48 个字节。

🐔5.二维数组的初始化


二维数组的初始化可以按行分段赋值,也可按行连续赋值。


int arr4[3][4] = { {1,2,3},{4,5,6},{7,8,9},{10,11,12} };
int arr5[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}


这两种赋初值的结果是完全相同的。


对于二维数组的初始化还要注意以下几点:


可以只对部分元素赋值,未赋值的元素自动取“零”值。

如果对全部元素赋值,那么第一维的长度可以不给出。

二维数组可以看作是由一维数组嵌套而成的;如果一个数组的每个元素又是一个数组,那么它就是二维数组。当然,前提是各个元素的类型必须相同。


🦀6.二维数组的使用


二维数组依旧是利用下标访问!!!


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



打印地址:



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



二维数组在逻辑(表现形式)上可理解为矩阵形式(分行分列),但其物理存储形式却是连续的,即存完第一行,在其后面接着存储第二行,第三行,…,如无特殊说明,本书中涉及对二维数组的表述一般指的是其逻辑形式即矩阵形式。



🙈7.数组作为函数参数


数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用;另一种是把数组名作为函数的形参和实参使用。 数组元素就是下标变量,它与普通变量并无区别。 因此它作为函数实参使用与普通变量是完全相同的,在发生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。


🦄数组元素作函数实参


数组元素就是下标变量,它与普通变量并无区别。 因此它作为函数实参使用与普通变量是完全相同的,在发生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。


🐧数组名作为函数参数


用数组名作函数参数与用数组元素作实参有几点不同。


用数组元素作实参时,只要数组类型和函数的形参变量的类型一致,那么作为下标变量的数组元素的类型也和函数形参变量的类型是一致的。因此,并不要求函数的形参也是下标变量。换句话说,对数组元素的处理是按普通变量对待的。用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。当形参和实参二者不一致时,即会发生错误。

在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元。在函数调用时发生的值传送是把实参变量的值赋予形参变量。在用数组名作函数参数时,不是进行值的传送,即不是把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。那么,数据的传送是如何实现的呢?在我们曾介绍过,数组名就是数组的首地址。因此在数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段内存空间。



上图说明了这种情形。图中设a为实参数组,类型为整型。a占有以2000为首地址的一块内存区。b为形参数组名。当发生函数调用时,进行地址传送,把实参数组a的首地址传送给形参数组名b,于是b也取得该地址2000。于是a,b两数组共同占有以2000为首地址的一段连续内存单元。从图中还可以看出a和b下标相同的元素实际上也占相同的两个内存单元(整型数组每个元素占二字节)。例如a[0]和b[0]都占用2000和2001单元,当然a[0]等于b[0]。类推则有a[i]等于b[i]。

目录
相关文章
|
5天前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
1月前
|
C语言
王桂林C语言从放弃到入门课程
课程目标16天,每天6节课,每节40分钟课堂实录,带你征服C语言,让所有学过和没有学过C语言的人,或是正准备学习C语言的人,找到学习C语言的不二法门。适用人群所有学过和没有学过C语言的人,或是正准备学习C语言的人!
25 2
王桂林C语言从放弃到入门课程
|
1月前
|
C语言
在C语言中数组作为函数参数的应用与示例
在C语言中数组作为函数参数的应用与示例
15 0
|
8天前
|
存储 自然语言处理 编译器
振南技术干货集:振南当年入门C语言和单片机的那些事儿(3)
振南技术干货集:振南当年入门C语言和单片机的那些事儿(3)
|
6天前
|
存储 C语言
C语言中字符串的引用与数组元素操作
C语言中字符串的引用与数组元素操作
12 0
|
8天前
|
算法 C语言 芯片
振南技术干货集:振南当年入门C语言和单片机的那些事儿(1)
振南技术干货集:振南当年入门C语言和单片机的那些事儿(1)
|
26天前
|
编译器 程序员 C语言
【C语言】变长数组,二分查找和数组之间自动替换的实现
【C语言】变长数组,二分查找和数组之间自动替换的实现
|
26天前
|
存储 C语言
【C语言数组】创建、初始化、以及使用2
【C语言数组】创建、初始化、以及使用
|
1月前
|
Java C语言 C++
C语言由入门到精通(1)介绍与数据类型
C语言由入门到精通(1)介绍与数据类型
|
1月前
|
存储 程序员 C语言
C语言中的结构体数组
C语言中的结构体数组
9 0