当前位置:   article > 正文

C语言学习之路(基础篇)—— 数组和字符串(上)_用括号括起来的三行四列是什么

用括号括起来的三行四列是什么

说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

概述

在程序设计中,为了方便处理数据把具有相同类型的若干变量按有序形式组织起来——称为数组。

数组就是在内存中连续的相同类型的变量空间。同一个数组所有的成员都是相同的数据类型,同时所有的成员在内存中的地址是连续的。

数组: 将若干个相同数据类型的变量存放在一个连续的内存空间。数组的最小单位是元素,数组中的每一个元素都是一个变量

在这里插入图片描述

构造类型: 将基本类型构建成类型。
相同类型的数据存放在一个集合中,这种的构造类型就是数组。
数组属于构造数据类型:

  • 一个数组可以分解为多个数组元素:这些数组元素可以是基本数据类型或构造类型。
int a[10];  // 数值数组
struct Stu boy[10]; // 结构数组
  • 1
  • 2
  • 按数组元素类型的不同,数组可分为:数值数组、字符数组、指针数组、结构数组等类别。
int a[10]; // 数值数组
char s[10]; // 字符数组
char *p[10]; // 指针数组
struct Stu boy[10]; // 结构数组
  • 1
  • 2
  • 3
  • 4

通常情况下,数组元素下标的个数也称为维数,根据维数的不同,可将数组分为一维数组、二维数组、三维数组、四维数组等。通常情况下,我们将二维及以上的数组称为多维数组。

一维数组

1) 一维数组的定义和使用

数组名字符合标识符的书写规定(数字、英文字母、下划线)
数组名不能与其它变量名相同,同一作用域内是唯一的
方括号[]中常量表达式表示数组元素的个数

int a[3]表示数组a有3个元素
其下标从0开始计算,因此3个元素分别为a[0],a[1],a[2]
  • 1
  • 2

定义数组时[]内最好是常量,使用数组时[]内即可是常量,也可以是变量

示例:

#include<stdio.h>


int main() {
    // 数组名和变量名定义方法一样
    //符号与[]结合代表这个是一个数组
    //数组中的元素的个数由[]里面的数值决定
    //每个元素的类型,数组名前面的类型决定
    //数值数组不能整体操作
    //数组的每一个元素都是变量,可以被改变赋值
    int i = 5;
    int num[10];
    //int sum[i]; //定义数组时,[]里面的值不能为变量,只能为常量
    num[i] = 100; //使用时,[]里面的值可以为常量也可以是变量
    for (int j = 0;  j<10; j++)
    {
        printf("num[%d]=%d\n", j, num[j]);
    }
    char name[2];
    name[0] = 't';
    name[1] = 'g';
    for (int k = 0; k < 2; k++)
    {
        printf("%c", name[k]);
    }
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

在这里插入图片描述

2) 一维数组的初始化

定义数组的同时进行赋值,称为初始化。全局数组若不初始化,编译器将其初始化为零。局部数组若不初始化,内容为随机值。

示例:

#include<stdio.h>


int main() {
    // 数组的初始化
    int num[5] = { 1,2,3,4,5 };
    int sum[5] = { 1,2 }; // 如果数组只初始化部分元素,其他元素被初始化为0
    int num2[10] = {0}; //将数组所有元素初始化为0
    int sum2[5] = { [3] = 3 }; // 给sum2数组下标为3的元素赋值3
    //int age[]; err  定义时没有告知有几个元素
    int  age[] = { 17,18,19 };//如果定义时,[]中没有值,这个数组的元素个数由{}里面的元素个数决定
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", num[i]);
    }
    printf("\n");
    for (int j = 0; j < 5; j++)
    {
        printf("%d ", sum[j]);
    }
    printf("\n");
    for (int j = 0; j < 10; j++)
    {
        printf("%d ", num2[j]);
    }
    printf("\n");
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", sum2[i]);
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在这里插入图片描述

3) 一维数组的大小

示例:

#include<stdio.h>


int main() {

    // 数组的大小
    int num[10] = { 1,2,3,4,5,6,7,8,9,10 };
    printf("%d\n", sizeof(num)); // 40    10个int类型,每个int类型占4字节
    // 数组的元素个数
    int n = sizeof(num) / sizeof(num[0]);
    printf("n=%d\n", n);
    // 通过for循环打印num数组的元素
    for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
    {   
        printf("num[%d]=%d\n", i, num[i]);
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述

4) 一维数组数组名

数组名是一个地址的常量,代表数组中首元素的地址。

4.1 数据在内存中的地址

在这里插入图片描述

4.2 数组在内存中的存储

在这里插入图片描述
补充: & 在C语言中有两种意思,一种是取地址符,是单目运算符;另一种是位运算符,表示“按位与”,是双目运算符。

示例:

#include<stdio.h>


int main() {
	int a[5];
	// &a[0]  第0个元素的地址
	printf("%u\n", &a[0]); // 19920604
	printf("%u\n", a); // 19920604
	// &a  整个数组地址
	printf("%u\n", &a); // 19920604
	printf("+++++++++++++++\n");
	printf("%u\n", &a[0]+1); // 19920608
	printf("%u\n", a+1); // 19920608
	printf("%u\n", &a+1); // 19920624

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述

5) 强化训练

5.1 一维数组的最值

#include<stdio.h>


int main() {
	int num[10] = { 12,0,32,-21,432,34,87,3,-9,101 };
	int max = num[0];
	int min = num[0];
	for (int i = 0; i < sizeof(num)/sizeof(num[0]); i++)
	{
		if (num[i]>max)
		{
			max = num[i];
		}
		else if (num[i]<min )
		{
			min = num[i];
		}
	}
	printf("max=%d, min=%d", max, min); // max=432, min=-21
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5.2 一维数组的逆置

int main() {
	// 数组的逆置
	// 方法1
	int num[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	int j = sizeof(num) / sizeof(num[0]) - 1;
	int temp;

	while (i<j)
	{
		temp = num[i];
		num[i] = num[j];
		num[j] = temp;
		i++;
		j--;
	}
	for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
	{
		printf("%d ", num[i]);
	}
	printf("\n");
	// 方法2
	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int b[10];
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		for (int j = sizeof(a) / sizeof(a[0])-1; j >=0 ; j--)
		{
			b[j] = a[i];
			i++;
		}
	}
	for (int i = 0; i < sizeof(b) / sizeof(b[0]); i++)
	{
		printf("%d ", b[i]);
	}


	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

在这里插入图片描述

5.3 冒泡法排序

冒泡排序的原理是: 从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。

在这里插入图片描述
在这里插入图片描述

示例:

#include<stdio.h>


int main() {
	// 数组的排序—冒泡排序法—从小到大
	int a[10] = { 2,-5,-7,1,-4,8,3,-9,6,0 };
	int n = sizeof(a) / sizeof(a[0]);
	for (int i = 0; i < n-1; i++) //比较的轮数
	{	// 因为每次比较的次数都要减1,刚好i每次加1,所以每一轮比较的次数就是n-1-i
		for (int j = 0; j < n-1-i; j++) // 每一轮比较的次数
		{
			if (a[j]>a[j+1])  // 交换位置
			{
				int temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
	for (int i = 0; i < n; i++) 
	{
		printf("%d ", a[i]); // -9 -7 -5 -4 0 1 2 3 6 8
	}
	printf("\n");
	// 数组的排序—冒泡排序法—从大到小
	int b[10] = { 2,-5,-7,1,-4,8,3,-9,6,0 };
	for (int i = 0; i < sizeof(b) / sizeof(b[0]) - 1; i++) //比较的轮数
	{	// 因为每次比较的次数都要减1,刚好i每次加1,所以每一轮比较的次数就是n-1-i
		for (unsigned int j = 0; j < sizeof(b) / sizeof(b[0]) - 1 - i; j++) // 每一轮比较的次数
		{
			if (b[j] < b[j + 1])  // 交换位置
			{
				int temp = b[j];
				b[j] = b[j + 1];
				b[j + 1] = temp;
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		printf("%d ", b[i]); // 8 6 3 2 1 0 -4 -5 -7 -9
	}

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

在这里插入图片描述

二维数组

1) 二维数组的定义和使用

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

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

其中常量表达式1表示第一维下标的长度,常量表达式2 表示第二维下标的长度。

int a[3][4];

  • 命名规则同一维数组

  • 定义了一个三行四列的数组,数组名为a其元素类型为整型,该数组的元素个数为3×4个,即:

    在这里插入图片描述
    在这里插入图片描述

二维数组a是按行进行存放的,先存放a[0]行,再存放a[1]行、a[2]行,并且每行有四个元素,也是依次存放的。

  • 二维数组在概念上是二维的:其下标在两个方向上变化,对其访问一般需要两个下标。
  • 在内存中并不存在二维数组,二维数组实际的硬件存储器是连续编址的,也就是说内存中只有一维数组,即放完一行之后顺次放入第二行,和一维数组存放方式是一样的。

示例:

#include<stdio.h>


int main() {
	// 定义一个3行4列的二维数组
	int a[3][4];
	// 二维数组的每一个元素也是一个变量
	a[0][0] = 10;
	a[1][1] = 20;
	a[2][3] = 30;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}


	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这里插入图片描述

// a数组的大小
printf("%d", sizeof(int [3][4]));  // 48 3*4=12  12*4B(int) = 48 字节
printf("%d", sizeof(a)); //48  
  • 1
  • 2
  • 3

2) 二维数组的初始化

示例:

#include<stdio.h>


int main() {
	// 第一种写法
	int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	// 第二种写法
	int b[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	//定义二维数组时,不能省略列的下标,但可以省略行的下标
	//int c[][] = { 1,2,3,4,5 }; // err  列的下标不能省略
	// 给二维数组部分元素初始化,其他元素为0
	int d[][3] = { 1,2,3,4,5 };  // 只定义了列的下标为3,也就是一个一维数组有3个元素,超出3个的元素,自动添加一行,那么就是2行
								 // 即第一行为 1,2,3 第二行为4,5,0(未初始化的元素,默认为0)

	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++) 
		{
			printf("%d ", d[i][j]);
		
		}
		printf("\n");
	}
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

在这里插入图片描述

3) 二维数组的行和列

#include<stdio.h>


int main() {

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

	// 元素的个数
	int n = sizeof(a) / sizeof(a[0][0]); // 二维数组的总大小除以 一个元素的大小=元素个数
	// 数组的行
	int line = sizeof(a) / sizeof(a[0]); // 二维数组总大小除以 一行的大小=行数
	// 数组的列
	int column = sizeof(a[0]) / sizeof(a[0][0]); // 二维数组一行的大小除以 一个元素的大小 = 列数

	printf("%d个元素 %d行 %d列", n, line, column); // 12个元素 3行 4列

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

4) 二维数组数组名

在这里插入图片描述
示例:

#include<stdio.h>


int main() {

	int a[2][3];

	printf("%u\n", &a[0][0]); // 7338640
	printf("%u\n", a[0]); // 7338640
	printf("%u\n", &a[0]); // 7338640
	printf("%u\n", a); // 7338640
	printf("%u\n", &a); // 7338640
	printf("+++++++++++++++\n");
	printf("%u\n", &a[0][0]+1); // 7338644
	printf("%u\n", a[0]+1); // 7338644
	printf("%u\n", &a[0]+1); // 7338652
	printf("%u\n", a+1); // 7338652
	printf("%u\n", &a+1); // 7338664
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这里插入图片描述

5) 强化训练

已知: 老大的语数外成绩为80、75、 56,老二的语数外成绩为59、65、 71,老三的语数外成绩为59、63、70,老四的语数外成绩为85、45、90,老五的语数外成绩为76、77、45。

在这里插入图片描述

求1: 各科的平均成绩

#include<stdio.h>


int main() {
	//二维数组:  五行、三列
	//行代表人:  老大到老五
	//列代表科目:语、数、外
	float a[5][3] = { { 80, 75, 56 }, { 59, 65, 71 }, { 59, 63, 70 }, { 85, 45, 90 }, { 76, 77, 45 } };
	int person_line = sizeof(a) / sizeof(a[0]);  //行数  人员
	int lesson_column = sizeof(a[0]) / sizeof(a[0][0]);  // 列数  课程
	float lesson_aver[3] = {0};  // 定义一个数组,用于保存三个科目的平均分
	int person_low[3] = { 0 };  // 用于保存各科不及格人数
	for (int i = 0; i < lesson_column; i++)  // 列
	{	float sum = 0.0;  // 定义在行循环外好进行初始化,每一次sum的值都需要为0
		for (int j = 0; j < person_line; j++)  // 行
		{	
			// 每一列科目分数总和
			sum += a[j][i];  // 列不变,行变
			lesson_aver[i] = sum / person_line;  // 每一列科目分数的总和 除以 人数也就是数组行数等到每个科目的平均分
		}
	}
	// 各科的平均成绩
	for (int i = 0; i < sizeof(lesson_aver) / sizeof(lesson_aver[0]); i++)
	{
		printf("%f\n", lesson_aver[i]);
	}
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在这里插入图片描述

求2: 各科不及格的人数

#include<stdio.h>


int main() {
	//二维数组:  五行、三列
	//行代表人:  老大到老五
	//列代表科目:语、数、外
	float a[5][3] = { { 80, 75, 56 }, { 59, 65, 71 }, { 59, 63, 70 }, { 85, 45, 90 }, { 76, 77, 45 } };
	int lesson_line = sizeof(a) / sizeof(a[0]);  //行数  人员
	int person_column = sizeof(a[0]) / sizeof(a[0][0]);  // 列数  课程
	float lesson_aver[3] = {0};  // 定义一个数组,用于保存三个科目的平均分
	int person_low[3] = { 0 };  // 用于保存各科不及格人数
	for (int i = 0; i < person_column; i++)  // 列
	{	float sum = 0.0;  // 定义在行循环外好进行初始化,每一次sum的值都需要为0
		for (int j = 0; j < lesson_line; j++)  // 行
		{	
			// 每一列科目分数总和
			sum += a[j][i];  // 列不变,行变
			// 每一列科目不及格的人数
			if (a[j][i]<60)
			{
				person_low[i]++;  // 三个元素代表三科,外循环三列,所以在遍历每一列的科目时判断小于60的那么在person_low数组中的i元素+1计数即可
			}
			lesson_aver[i] = sum / lesson_line;  // 每一列科目分数的总和 除以 人数也就是数组行数等到每个科目的平均分
		}
	}
	// 各科的平均成绩
	for (int i = 0; i < sizeof(lesson_aver) / sizeof(lesson_aver[0]); i++)
	{
		printf("%f\n", lesson_aver[i]);
	}
	// 各科的不及格人数
	for (int i = 0; i < sizeof(person_low) / sizeof(person_low[0]); i++)
	{
		printf("%d\n", person_low[i]);
	}
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

在这里插入图片描述

多维数组(了解)

1) 多维数组的定义和使用

多维数组的定义与二维数组类似,其语法格式具体如下:

数组类型修饰符 数组名 [n1][n2]…[nn];

int a[2][3][4]; 定义了一个三维数组,有2个二维数组,每个二维数组有3个一维数组,每个一维数组有4个元素。
在这里插入图片描述

示例:

#include<stdio.h>


int main() {

	// 定义一个三维数组,有2个二维数组,每个二维数组有3个一维数组,每个一维数组有4个元素
	int a[2][3][4];

	a[0][0][0] = 10;
	a[0][2][3] = 20;
	a[1][0][0] = 30;
	a[1][2][3] = 40;

	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			for (int k = 0; k < 4; k++)
			{
				printf("%d ", a[i][j][k]);
			}
			printf("\n");
		}
		printf("\n");
	}
	// a数组的大小
	printf("%d\n", sizeof(int[2][3][4]));  // 96 2*3*4=24 两个二维数组[3][4]  24*4B(int) = 96 字节
	printf("%d", sizeof(a)); //96


	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在这里插入图片描述

2) 多维数组的初始化

示例:

#include<stdio.h>


int main() {
	// 第一种写法
	int a[2][3][4] = { {{1,2,3,4},{5,6,7,8},{9,10,11,12}},  {{13,14,15,16},{17,18,19,20},{21,22,23,24}} };
	// 第二种写法
	int b[2][3][4] = { {1,2,3,4,5,6,7,8,9,10,11,12},{13,14,15,16,17,18,19,20,21,22,23,24} };
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			for (int k = 0; k < 4; k++)
			{
				printf("%d ", a[i][j][k]);
			}
		}
		printf("\n");
	}
	printf("-------------------分割线-------------------\n");
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			for (int k = 0; k < 4; k++)
			{
				printf("%d ", b[i][j][k]);
			}
		}
		printf("\n");
	}


	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/492770
推荐阅读
相关标签
  

闽ICP备14008679号