Lesson5 数组和字符串(Lesson5 arrays and strings)

5.数字和字符串

5.1 概述

数组的定义方式: 数据类型 数组名[元素个数] = {x1,x2,x3}

#include <stdio.h>

int main()
{
    int arr[10] = { 9,4,2,1,2,3,10,22,55,12 };
	for (int i = 0; i < 10; i++)
	{
		printf("%d\t", arr[i]);
	}
    
}


输出:9 4 2 1 2 3 10 22 55 12

5.2 数组的定义与使用

int main()
{
	int arr[10] = { 9,4,2,1,5,3,10,22,55,12 };
	//下标为0的元素地址
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr[1]);
	printf("%p\n", &arr[2]);
	printf("%p\n", &arr[3]);
	printf("%p\n", &arr[4]);
	printf("%p\n", &arr[5]);
	printf("%p\n", &arr[6]);

	printf("%p\n", arr);//数组名是一个地址常量 指向数组首地址的常量
	printf("数组在内存中占得大小:%d\n", sizeof(arr));//数组名是一个地址常量 指向数组首地址的常量
	printf("数组元素的个数:%d\n", sizeof(arr)/sizeof(arr[0]));

	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d\n", arr[i]);
	}
	{

	}
	return 0;
}

输出:

00D3F874
00D3F878
00D3F87C
00D3F880
00D3F884
00D3F888
00D3F88C
00D3F874
数组在内存中占得大小:40
数组元素的个数:10
9
4
2
1
5
3
10
22
55
12

数组下标元素必须是常量,或者常量表达式

如果一开始用int i =5; arr[i],这样定义是不可以的

数组下标越界可能会报错,越界之后读取的就是内存中的数据,如果数据是不可以访问的,就会报错

#include<stdio.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", arr[-1]);
	for (int i = 0; i < 20; i++)
	{
		
		printf("%d\n", arr[i]);
		//数组下标越界
	}
	return 0;
}

输出:

-858993460
1
2
3
4
5
6
7
8
9
10
-858993460
2489552
4138131
1
7826608
7828632
1
7826608
7828632
2489644

十只小猪称体重:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define SIZE 10

int main() {
	int arr[SIZE];

	for (int i = 0; i < SIZE; i++)
	{
		scanf("%d", &arr[i]);
	}
	int max = 0;
	for (int i = 0; i < SIZE; i++)
	{
		if (arr[i] > max)
		{
			max = arr[i];
		}
	}
	printf("最重的小猪体重为:%d\n", max);
	return 0;
}

可以输出最大的那个数

冒泡排序:每次比较次数为元素个数-1-执行次数

#include<stdio.h>

int main()
{
	int arr[] = { 9,1,5,7,2,10,8,4,6,3 };
	for (int i = 0; i < 10-1; i++)//外层控制行
	{
		for (int j = 0; j < 10-1-i; j++)//内层控制列
		{
			if (arr[j] > arr[j + 1]) {//交换两个元素
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}

	for (int i = 0; i < 10; i++)
	{
		printf("%d\t", arr[i]);
	}
	return 0;
}

输出:1 2 3 4 5 6 7 8 9 10

5.3二维数组

#include<stdio.h>

int main()
{
	int arr[2][3] =
	{
		{1,2,3},
		{4,5,6}
	};

	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d\t", arr[i][j]);
		}
		printf("\n");
	}

	printf("二维数组大小为:%d\n", sizeof(arr));
	printf("二维数组一行大小为:%d\n", sizeof(arr[0]));
	printf("二维数组元素大小为:%d\n", sizeof(arr[0][0]));

	printf("二维数组行数:%d\n", sizeof(arr)/sizeof(arr[0]));
	printf("二维数组列数:%d\n", sizeof(arr[0])/sizeof(arr[0][0]));
	return 0;
}

输出:

1 2 3
4 5 6
二维数组大小为:24
二维数组一行大小为:12
二维数组元素大小为:4
二维数组行数:2
二维数组列数:3

int main()
{
	int arr[2][3] =
	{
		{1,2,3},
		{4,5,6}
	};
	//二维数组首地址
	printf("%p\n", arr);
	printf("%p\n", arr[0]);
	printf("%p\n", &arr[0][0]);
	printf("%p\n", &arr[0][1]);
	printf("%p\n", &arr[1]);


	return 0;
}

输出:

005FFB90
005FFB90
005FFB90
005FFB94
005FFB9C

int main()
{
	int arr[][3] = { 1,2,3,4,5,6,7 };//定义数组时,只有挨着数组名的那个括号可以被省略大小
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d\t", arr[i][j]);
		}
		printf("\n");
	}
}

输出:

1 2 3
4 5 6
7 0 0

打印学生成绩:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	//定义一个数组, 存储五名学生的三门成绩
	//求出每位学生的总成绩,平均成绩
	//求出每门学科的总成绩,平均成绩

	int arr[5][3];

	//获取学生成绩
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j <3 ; j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}

	//打印学生成绩
	for (int i = 0; i < 5; i++)
	{
		int sum = 0;
		for (int j = 0; j < 3; j++)
		{
			sum += arr[i][j];
		}
		printf("第%d名学生总成绩为:%d,平均成绩为:%d\n", i+1,sum,sum/3);

	}

	for (int i = 0; i < 3; i++)
	{
		int sum = 0;
		for (int j = 0; j < 5; j++)
		{
			sum += arr[j][i];
		}
		printf("第%d门功课总成绩为:%d,平均成绩为:%d\n", i + 1, sum, sum / 5);

	}
	return 0;
}

输入输出:

1 23 45
12 786 45
56 89 23
123 7891 4545
7878 356 89543
第1名学生总成绩为:69,平均成绩为:23
第2名学生总成绩为:843,平均成绩为:281
第3名学生总成绩为:168,平均成绩为:56
第4名学生总成绩为:12559,平均成绩为:4186
第5名学生总成绩为:97777,平均成绩为:32592
第1门功课总成绩为:8070,平均成绩为:1614
第2门功课总成绩为:9145,平均成绩为:1829
第3门功课总成绩为:94201,平均成绩为:18840

三维数组和二维数组类似。

5.4 字符数组和字符串

字符串是特殊类型的字符数组

#include<stdio.h>

int main()
{
	//定义字符数组
	char arr[5] = {'h','l','l','e','o'};

	printf("%d\n", sizeof(arr));
	//字符串的结束为\0
	char arr2[] = { "hello" };//这里面是有\0在结尾的
	//数字0等同于\0,但是不等同于'0'
	for (int i = 0; i < sizeof(arr); i++)
	{
		printf("%c", arr[i]);
	}
	printf("\n");
	for (int i = 0; i < sizeof(arr); i++)
	{
		printf("%c", arr2[i]);
	}
	printf("\n");
	printf("arr2的大小为:%d\n",sizeof(arr2));

	return 0;
}

输出:

5
hlleo
hello
arr2的大小为:6

int main()
{
	//定义字符数组存储字符串
	char ch[10];

	scanf("%s", ch);//ch本身就是一个地址,所以不用加&符号
	//scanf接收空格或者换行结束,所以中间不能用空格隔开输入的内容
	printf("%s", ch);
	return 0;

}

输入:hello wor
输出:hello

字符串的拼接:

int main()
{
	char ch1[] = "hello";
	char ch2[] = "world";
	char ch3[20];

	int i = 0;
	int j = 0;
	while (ch1[i] != '\0')
	{
		ch3[i] = ch1[i];
		i++;
	}
	while (ch1[j] != '\0')
	{
		ch3[i+j] = ch2[j];
		j++;
	}

	ch3[i + j] = '\0';

	printf("%s", ch3);
	return 0;

}

输出:helloworld

字符数组与字符串的区别:

c语言中没有字符串这种数据类型,可以通过char的数组替代

字符串一定是一个char数组,而char数组不一定都是字符串(没有\0结尾的就不是字符串)

数字0和字符’0’等价,以它们结尾的char数组就是字符串,但是如果数组没有以数字0结尾,那么就是普通数组。

扫描输入字符串时,可以在%s之间限定输入个数,比如%9s,这样前面定义一个arr[10],就不会越界乱码了

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	char ch[1000];

	//gets(ch);//通过键盘获取一个字符串
	//gets接收字符串可以带空格
	scanf("%[^\n]", ch); //通过正则表达式,scanf也可以接收空格输入了,在遇到换行符时才会输出

	printf("%s\n", ch);

	return 0;
}

输入:daskl, ,e wqoeafk dsfm,z.cmz
输出:daskl, ,e wqoeafk dsfm,z.cmz

fgets函数:从stream指定的文件内读入字符,保存到s所指定的内存空间,直到出现换行字符、读到文件结尾或是已读了size-1个字符为止,最后会自动加上字符‘\0’,作为字符串结尾

char *fgets(char *s,int size,FILE *stream);

s:字符串,size:指定最大读取字符串的长度(size-1),stream:文件指针,如果读键盘输入的字符串,固定写为stdin

int main()
{
	char ch[10];
	fgets(ch, sizeof(ch), stdin);//可以接收空格,不会越界,在输入数据少于限定数目时会自动添加\n

	printf("%s", ch);

	return 0;
}

puts函数:输出s字符串,在输出完成后会自动输出一个\n

参数:s——字符串首地址

int puts(const char *s)

puts(“”),可以直接实现自动换行

int main()
{
	char ch[] = "helloWorld";
	puts(ch);//自带换行
	puts("hello\0 World");//遇到\0会停止

	return 0;

}

输出:

helloWorld
hello

fputs():将str所指定的字符串写入到stream指定的文件中,字符串结束符’\0’不写入文件。

参数:str:字符串,stream:文件指针,如果把字符串输出到屏幕,固定写为stdout

int fputs(const char *str,FILE *stream);

int main()
{
	char ch[] = "Hello World";
	fputs(ch, stdout);
	return 0;
}

Hello World

strlen函数:计算指定字符串s的长度,不包含结束符号\0

参数:s——字符串首地址

头文件需要导入:#include <string.h>

#include<stdio.h>
#include<string.h>

int main()
{
	//计算字符串有效个数
	char ch[] = "hello World";

	printf("数组大小为:%d",sizeof(ch) );
	printf("字符串长度为:%d",strlen(ch) );

}

数组大小为:12字符串长度为:11

————————

5. Numbers and strings

5.1 general

Array definition method: data type array name [number of elements] = {x1, X2, X3}

#include <stdio.h>

int main()
{
    int arr[10] = { 9,4,2,1,2,3,10,22,55,12 };
	for (int i = 0; i < 10; i++)
	{
		printf("%d\t", arr[i]);
	}
    
}


Output: 9 4 2 1 2 3 10 22 55 12

5.2 definition and use of array

int main()
{
	int arr[10] = { 9,4,2,1,5,3,10,22,55,12 };
	//下标为0的元素地址
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr[1]);
	printf("%p\n", &arr[2]);
	printf("%p\n", &arr[3]);
	printf("%p\n", &arr[4]);
	printf("%p\n", &arr[5]);
	printf("%p\n", &arr[6]);

	printf("%p\n", arr);//数组名是一个地址常量 指向数组首地址的常量
	printf("数组在内存中占得大小:%d\n", sizeof(arr));//数组名是一个地址常量 指向数组首地址的常量
	printf("数组元素的个数:%d\n", sizeof(arr)/sizeof(arr[0]));

	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d\n", arr[i]);
	}
	{

	}
	return 0;
}

Output:

00D3F874
00D3F878
00D3F87C
00D3F880
00D3F884
00D3F888
00D3F88C
00D3F874
Size of array in memory: 40
Number of array elements: 10
nine
four
two
one
five
three
ten
twenty-two
fifty-five
twelve

< strong > array subscript elements must be constants or constant expressions < / strong >

If you start with int i = 5; Arr [i], this definition is not allowed

< strong > an error may be reported if the array subscript is out of bounds. After it is out of bounds, the data in memory will be read. If the data is inaccessible, an error will be reported < / strong >

#include<stdio.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", arr[-1]);
	for (int i = 0; i < 20; i++)
	{
		
		printf("%d\n", arr[i]);
		//数组下标越界
	}
	return 0;
}

Output:

-858993460
one
two
three
four
five
six
seven
eight
nine
ten
-858993460
two million four hundred and eighty-nine thousand five hundred and fifty-two
four million one hundred and thirty-eight thousand one hundred and thirty-one
one
seven million eight hundred and twenty-six thousand six hundred and eight
seven million eight hundred and twenty-eight thousand six hundred and thirty-two
one
seven million eight hundred and twenty-six thousand six hundred and eight
seven million eight hundred and twenty-eight thousand six hundred and thirty-two
two million four hundred and eighty-nine thousand six hundred and forty-four

Weigh ten piglets:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define SIZE 10

int main() {
	int arr[SIZE];

	for (int i = 0; i < SIZE; i++)
	{
		scanf("%d", &arr[i]);
	}
	int max = 0;
	for (int i = 0; i < SIZE; i++)
	{
		if (arr[i] > max)
		{
			max = arr[i];
		}
	}
	printf("最重的小猪体重为:%d\n", max);
	return 0;
}

The largest number can be output

Bubble sort: the number of elements per comparison is – 1 – execution times

#include<stdio.h>

int main()
{
	int arr[] = { 9,1,5,7,2,10,8,4,6,3 };
	for (int i = 0; i < 10-1; i++)//外层控制行
	{
		for (int j = 0; j < 10-1-i; j++)//内层控制列
		{
			if (arr[j] > arr[j + 1]) {//交换两个元素
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}

	for (int i = 0; i < 10; i++)
	{
		printf("%d\t", arr[i]);
	}
	return 0;
}

Output: 1 2 3 4 5 6 7 8 9 10

5.3 two dimensional array

#include<stdio.h>

int main()
{
	int arr[2][3] =
	{
		{1,2,3},
		{4,5,6}
	};

	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d\t", arr[i][j]);
		}
		printf("\n");
	}

	printf("二维数组大小为:%d\n", sizeof(arr));
	printf("二维数组一行大小为:%d\n", sizeof(arr[0]));
	printf("二维数组元素大小为:%d\n", sizeof(arr[0][0]));

	printf("二维数组行数:%d\n", sizeof(arr)/sizeof(arr[0]));
	printf("二维数组列数:%d\n", sizeof(arr[0])/sizeof(arr[0][0]));
	return 0;
}

Output:

1 2 3
4 5 6
Two dimensional array size: 24
One row size of two-dimensional array: 12
Two dimensional array element size: 4
Two dimensional array rows: 2
Number of 2D array columns: 3

int main()
{
	int arr[2][3] =
	{
		{1,2,3},
		{4,5,6}
	};
	//二维数组首地址
	printf("%p\n", arr);
	printf("%p\n", arr[0]);
	printf("%p\n", &arr[0][0]);
	printf("%p\n", &arr[0][1]);
	printf("%p\n", &arr[1]);


	return 0;
}

Output:

005FFB90
005FFB90
005FFB90
005FFB94
005FFB9C

int main()
{
	int arr[][3] = { 1,2,3,4,5,6,7 };//定义数组时,只有挨着数组名的那个括号可以被省略大小
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d\t", arr[i][j]);
		}
		printf("\n");
	}
}

Output:

1 2 3
4 5 6
7 0 0

Print student grades:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	//定义一个数组, 存储五名学生的三门成绩
	//求出每位学生的总成绩,平均成绩
	//求出每门学科的总成绩,平均成绩

	int arr[5][3];

	//获取学生成绩
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j <3 ; j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}

	//打印学生成绩
	for (int i = 0; i < 5; i++)
	{
		int sum = 0;
		for (int j = 0; j < 3; j++)
		{
			sum += arr[i][j];
		}
		printf("第%d名学生总成绩为:%d,平均成绩为:%d\n", i+1,sum,sum/3);

	}

	for (int i = 0; i < 3; i++)
	{
		int sum = 0;
		for (int j = 0; j < 5; j++)
		{
			sum += arr[j][i];
		}
		printf("第%d门功课总成绩为:%d,平均成绩为:%d\n", i + 1, sum, sum / 5);

	}
	return 0;
}

Input / output:

1 23 45
12 786 45
56 89 23
123 7891 4545
7878 356 89543
The total score of the first student is 69 and the average score is 23
The total score of the second student is 843 and the average score is 281
The total score of the third student is 168 and the average score is 56
The total score of the fourth student is 12559 and the average score is 4186
The total score of the fifth student is 97777, and the average score is 32592
The total score of the first course is 8070 and the average score is 1614
The total score of the second course is 9145 and the average score is 1829
The total score of the third course is 94201, and the average score is 18840

3D arrays are similar to 2D arrays.

5.4 character arrays and strings

A string is a special type of character array

#include<stdio.h>

int main()
{
	//定义字符数组
	char arr[5] = {'h','l','l','e','o'};

	printf("%d\n", sizeof(arr));
	//字符串的结束为\0
	char arr2[] = { "hello" };//这里面是有\0在结尾的
	//数字0等同于\0,但是不等同于'0'
	for (int i = 0; i < sizeof(arr); i++)
	{
		printf("%c", arr[i]);
	}
	printf("\n");
	for (int i = 0; i < sizeof(arr); i++)
	{
		printf("%c", arr2[i]);
	}
	printf("\n");
	printf("arr2的大小为:%d\n",sizeof(arr2));

	return 0;
}

Output:

five
hlleo
hello
The size of arr2 is: 6

int main()
{
	//定义字符数组存储字符串
	char ch[10];

	scanf("%s", ch);//ch本身就是一个地址,所以不用加&符号
	//scanf接收空格或者换行结束,所以中间不能用空格隔开输入的内容
	printf("%s", ch);
	return 0;

}

Input: Hello wor
Output: Hello

String splicing:

int main()
{
	char ch1[] = "hello";
	char ch2[] = "world";
	char ch3[20];

	int i = 0;
	int j = 0;
	while (ch1[i] != '\0')
	{
		ch3[i] = ch1[i];
		i++;
	}
	while (ch1[j] != '\0')
	{
		ch3[i+j] = ch2[j];
		j++;
	}

	ch3[i + j] = '\0';

	printf("%s", ch3);
	return 0;

}

输出:helloworld

Difference between character array and string:

There is no string data type in C language, which can be replaced by char array

The string must be a char array, and the char array is not necessarily a string (the string without the end of \ 0 is not a string)

The number 0 is equivalent to the character ‘0’. The char array ending with them is a string, but if the array does not end with the number 0, it is an ordinary array.

< strong > when scanning the input string, you can limit the number of inputs between% s, such as% 9s, so that an arr [10] is defined in front, and there will be no cross-border garbled code < / strong >

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	char ch[1000];

	//gets(ch);//通过键盘获取一个字符串
	//gets接收字符串可以带空格
	scanf("%[^\n]", ch); //通过正则表达式,scanf也可以接收空格输入了,在遇到换行符时才会输出

	printf("%s\n", ch);

	return 0;
}

输入:daskl, ,e wqoeafk dsfm,z.cmz
输出:daskl, ,e wqoeafk dsfm,z.cmz

< strong > fgets function: read characters from the file specified by stream and save them to the memory space specified by S. until a newline character appears, the end of the file is read, or the size-1 character has been read, the character ‘\ 0’ will be automatically added as the end of the string < / strong >

char *fgets(char *s,int size,FILE *stream);

s: String, size: Specifies the length of the maximum read string (size-1). Stream: file pointer. If you read the string entered by the keyboard, it is written as stdin

int main()
{
	char ch[10];
	fgets(ch, sizeof(ch), stdin);//可以接收空格,不会越界,在输入数据少于限定数目时会自动添加\n

	printf("%s", ch);

	return 0;
}

< strong > puts function: outputs s string. After the output is completed, a string will be automatically output. \ n < / strong >

Parameter: s — first address of string

int puts(const char *s)

Puts (“”), which can directly realize automatic line feed

int main()
{
	char ch[] = "helloWorld";
	puts(ch);//自带换行
	puts("hello\0 World");//遇到\0会停止

	return 0;

}

Output:

helloWorld
hello

< strong > fputs(): writes the string specified by STR to the file specified by stream, and the string terminator ‘\ 0’ is not written to the file

Parameters: STR: string, stream: file pointer. If the string is output to the screen, it is written as stdout

int fputs(const char *str,FILE *stream);

int main()
{
	char ch[] = "Hello World";
	fputs(ch, stdout);
	return 0;
}

Hello World

< strong > strlen function: calculates the length of the specified string s, excluding the ending symbol \ 0 < / strong >

Parameter: s — first address of string

Header file needs to be imported: #include & lt; string.h>

#include<stdio.h>
#include<string.h>

int main()
{
	//计算字符串有效个数
	char ch[] = "hello World";

	printf("数组大小为:%d",sizeof(ch) );
	printf("字符串长度为:%d",strlen(ch) );

}

Array size: 12 string length: 11