数组是一种数据结构,它允许批量产生多个相同类型的变量,这些变量称为数组元素。数组在内存中顺序存放,使得数据的访问和管理变得高效。
为什么要引入数组的概念呢?
问题: 一个班有40名学生,存储这40名学生某一门课程的成绩,计算出总成绩、平均成绩等,如何实现?
思路: 我们可以定义:40个浮点变量,例如: float score1,score2,.....,score40;
写出的程序,是否太麻烦了?!如果4000名学生的成绩呢?
既然都是相同类型的变量,我是否可以写在一起呢,这就可以用数组来实现:
float score[40]={88.5,90.0,78.3,...,98.0};//把40个学生的成绩存放在长度为40的数组里,表示起来就很简洁
下面我们就来学习如何定义数组和使用数组。
一维数组的一般形式为:类型说明符 数组名[长度];
int a[2+3];
//整型常量表达式#define N 5
int a[N];
//整型符号常量int a[5];
定义了一个长度为5的整型数组。数组定义完后,就可以使用其数组元素了,数组元素表示的一般形式为:数组名[下标]
a[0]
表示数组的第一个元素。//直接声明int类型数组,数组长度为3,不初始化数组,元素的值为0(或不确定)
int a[3];
//对全部数组元素进行初始化
int a[3] = {3, 1, 5};
//省略数组长度,也可以根据后面的赋值来决定数组长度
int c[] = {1, 2, 3};
//对部分数组元素初始化,数组长度不能省略, 比如这里仅仅是为前三个设定了初始值,其余未赋值元素的值为0(或不确定)
int b[10] = {1, 2, 4};
//我们也可以通过 [下标] = 赋值, 的形式来指定某一位的初始值,注意下标是从0开始的,第一个元素就是第0个下标位置,比如这里数组容量为10,那么最多到9
int c[10] = {1, 2, [4] = 777, [9] = 666};
输入学生 10 门课程的成绩,输出这些成绩,并输出总成绩和平均分
#include <stdio.h>
int main() {
float scores[10];
float sum = 0;
for (int i = 0; i < 10; i++) {
scanf("%f", &scores[i]);
}
for (int i = 0; i < 10; i++) {
sum += scores[i];
}
float average = sum / 10;
for (int i = 0; i < 10; i++) {
printf("%f ", scores[i]);
}
printf("Sum:%.2f\nAverage: %.2f\n", sum,average);
return 0;
}
int arr[][2] = {{20, 10}, {18, 9}}; //可以看到,数组里面存放的居然是数组
//存放的内层数组的长度是需要确定的,存放数组的数组和之前一样,可以根据后面的值决定
类型说明符 数组名[长度1][长度2];
例如:int a[2][3];
定义了一个2行3列的整型二维数组,数组名是 a。
int arr[3][12] = {{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //2020年是闰年,2月有29天
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
$$
\begin{cases}
a_{11}x_1&+&a_{12}x_2&+&\cdots&+a_{1n}x_n&=&b_1\
&&&&\vdots\
a_{n1}x_1&+&a_{n2}x_2&+&\cdots&+a_{nn}x_n&=&b_n&
\end{cases}
$$
数组(矩阵)表示N元一次方程组:
$$
\left[ \begin{matrix}
a_{11} & a_{12} & \cdots & a_{1n} \
a_{21} & a_{22} & \cdots & a_{2n} \
\vdots & \vdots & \ddots & \vdots \
a_{n1} & a_{n2} & \cdots & a_{nn} \
\end{matrix} \right] \times
\begin{bmatrix} x_{1} \ x_{2} \ \vdots \ x_{n} \ \end{bmatrix} =
\begin{bmatrix} b_{1} \ b_{2} \ \vdots \ b_{n} \ \end{bmatrix}
$$
double a[n][n],x[n],b[n];
二维数组元素表示的一般形式为:数组名[下标1][下标2]
a[0][0]
表示第一行第一列的元素。int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int a[][3] = {{1, 2, 3}, {4, 5, 6}};
int a[2][3] = {1};
输入10名学生物理、数学、外语3门课程的成绩,输出这些成绩,并输出这10名学生3门课程的平均分。
#include <stdio.h>
int main()
{
float a[10][3];
float sum[10]={0},ave[10];
int i,j;
for(i=0;i<10;i++)
{
for(j=0;j<3;j++)
{
scanf("%f",&a[i][j]);
}
}
for(i=0;i<10;i++)
{
for(j=0;j<3;j++)
{
sum[i]=sum[i]+a[i][j];
}
ave[i]=sum[i]/3;
}
for(i=0;i<10;i++)
{
for(j=0;j<3;j++)
{
printf("%.0f ",a[i][j]);
}
printf("\n");
}
for(i=0;i<10;i++)
{
printf("ave[%d]=%.0f\n",i,ave[i]);
}
}
当然除了二维还可以上升到三维、四维、多维
类型说明符 数组名[长度1][长度2].....[长度N];
int arr[2][2][2] = {{{1, 2}, {1, 2}}, {{1, 2}, {1, 2}}};
a[0][0]
表示第一行第一列的元素。有关多维数组,因为使用有限,暂时先介绍到这里。
int arr[2][2][2] = {{{1, 2}, {1, 2}}, {{1, 2}, {1, 2}}};
int arr[][2][2] = {{{1, 2}, {1, 2}}, {{1, 2}, {1, 2}}};
int a[2][3] = {1};
char ch;
ch=‘a’; //内放的是ASCII值,//即,65(十进制)=0100 0001(二进制)
C语言使用字符数组来存储字符串:char str[6]=“Hello”;
实际存放的ASCII码值
char 数组名[长度];
char a[6];
例如:char a[4]={‘a’, ‘b’, ‘c’, ‘d’};
初始化结果 a[0]值为‘a’,a[1]值为‘b’,a[2]值为‘c’,a[3]值为‘d’
char a[]={‘a’, ‘b’, ‘c’, ‘d’};
可以省略数组长度 4;char a[4]={‘a’, ‘b’};
初始化结果 a[0]值为‘a’,a[1]值为‘b’,a[2]值为‘\0’,a[3]值为‘\0’
例如:char a[6]=“Hello”;
初始化结果 a[0]值为‘H’,a[1]值为‘e’,a[2]值为‘l’,a[3]值为‘l’, a[4]值为‘o’, a[5]值为‘\0’;
char a[]=“Hello”;
可以省略数组长度6;char a[10]=“Hello”;
初始化结果a[0]值为‘H’,a[1]值为‘e’,a[2]值为‘l’,a[3]值为‘l’, a[4]值为‘o’, a[5]到a[9]的值均为‘\0’
#include <stdio.h>
int main()
{
char arr[5];
//输入字符
for (int i = 0; i < 5; i++)
{
printf("arr[%d] = ", i);
scanf(" %c", &arr[i]); // 输入{ 'a', 'b', 'c', 'd', 'e' }
}
//输出字符
for (int i = 0; arr[i] != NULL; i++)
{
printf("%c ", arr[i]);
}
printf("\n");
return 0;
}
#include <stdio.h>
int main()
{
char arr[15];
//输入字符串
printf("请输入15个字符内的字符串:\n");
scanf(" %14s", &arr); //使用%s格式说明符读取字符串,注意限制输入长度以防止溢出
//输出字符串
printf("您输入的字符串是:%s\n", arr);
return 0;
}
fgets
, gets
, fputs
, puts
, getchar
, 和 putchar
是C语言标准库中用于处理输入输出的函数。它们各自有不同的用途和行为,下面是对它们的详细解释:
stdin
或文件)读取最多n-1
个字符,或直到遇到换行符(换行符也会被读取并存储),或直到到达文件末尾。\0
)作为字符串的结束标志。stdin
读取一行,直到遇到换行符(换行符不会被存储)。str
(不包括空字符)写入到指定的输出流(如标准输出stdout
或文件)。str
和一个换行符写入到标准输出stdout
。stdin
读取下一个可用的字符。unsigned char
强制转换为int
,如果到达文件末尾或发生读取错误,则返回EOF
。unsigned char
)写入到标准输出stdout
。EOF
。#include <stdio.h>
int main() {
char str[100]; // 定义一个字符数组来存储字符串
// 输入字符串
printf("请输入一个99字符内的字符串:");
fgets(str, sizeof(str), stdin);
// 使用fgets从标准输入读取一行,并存储在str中
// fgets的第三个参数指定了最多读取的字符数(包括结尾的'\0')
/* if (fgets(str, sizeof(str), stdin) != NULL) {
// 检查是否读取到了换行符,并替换为字符串结束符'\0'(如果需要)
// 注意:如果输入的字符串长度达到了数组的大小-1(即sizeof(str)-1),
// 则换行符可能会被保留在字符串中,因为此时没有空间存储额外的'\0'了。
// 但在这个例子中,由于我们限制了最多读取99个字符,所以数组的第100个位置
// 是留给'\0'的,因此如果输入中包含了换行符,它会被替换掉。
size_t len = strlen(str);
if (len > 0 && str[len - 1] == '\n') {
str[len - 1] = '\0'; // 替换换行符为字符串结束符
}
} else {
// 处理读取错误(虽然在这个简单的例子中不太可能发生)
fprintf(stderr, "读取输入时发生错误。\n");
return 1; // 返回非零值表示程序异常结束
} */
//sizeof():数组变量的长度,strlen():数组字符串的长度
printf("%d %d\n", sizeof(str), strlen(str));
// 输出字符串
printf("您输入的字符串是:%s\n", str);
// 也可以使用fputs将字符串输出到标准输出(或其他文件流)
fputs(str, stdout); // 这行代码会输出字符串但不包括换行符
// 如果想要输出后换行,可以手动添加换行符
putchar('\n'); // 或者 fputs("\n", stdout);
return 0; // 返回零表示程序正常结束
}
字符串的运算,C语言中不能直接作+、-等运算,需要用函数做运算C库函数中提供了一些专门处理字符串的函数。下面介绍几种常见字符串处理函数:
strcpy(dest, src);
strcat(dest, src);
strcmp(str1, str2);
strlen(str);
示例
//设有定义
char str[] = "Hello";
//则语句
printf("%d %d", sizeof(str), strlen(str));
//的输出结果是(6 5)。
修改:修改中间一个元素的值,很简单,直接赋值即可。例如:a[i]= 修改的值或计算表达式;
查找:即,从数组所有元素中找到符合条件的第一个或全部元素。
查找数组中的特定元素,可以使用循环遍历数组。例如:
int findElement(int arr[], int size, int target) {
for (int i = 0; i < size; i++) {
if (arr[i] == target) {
return i; // 找到元素,返回下标
}
}
return -1; // 未找到元素,返回-1
}
排序:把数组中的元素,按升序(从小到大)或降序(从大大小),重新排列
常见的排序算法有冒泡排序、选择排序、插入排序等。以冒泡排序为例:
#include <stdio.h>
#include <conio.h>
int main()
{
int a[5] = { 7,6,5,4,3 };
int p, i, tmp;
{//检查原始顺序
printf("原始顺序:");
for (i = 0; i < 5; i++) printf("%d ", a[i]);
printf("\n");
}
for (p = 1; p < 5; p++)
{
for (i = 0; i < 5 - p; i++)
if (a[i] > a[i + 1]) { tmp = a[i]; a[i] = a[i + 1]; a[i + 1] = tmp; }
{//中间结果检查
printf("第%d轮: ", p);
for (i = 0; i < 5; i++) printf("%d ", a[i]);
printf("\n");
}
char a=_getch();// 等待输入一个字符(键盘)
}
return 0;
}
#include <stdio.h>
int main()
{
char arr[5] = {'a', 'b', 'c', 'd', 'e'}; // declaring the array
printf("原先: ");
for (int i = 0; arr[i] != NULL; i++) // 看一下
printf("%c ", arr[i]);
printf("\n");
arr[0] = '\0'; // 清数组 ,让数组第1个元素为‘\0’
printf("之后: ");
for (int i = 0; arr[i] != NULL; i++) // 再看一下,整个数组都无法输出
printf("%c ", arr[i]);
return 0;
}
#include <stdio.h>
#include <string.h>
int main()
{
char chin1[] = "我是一个学生";
char chin2[] = "我是a学生";
printf("第一个字符串长度:%d、占位:%d\n", strlen(chin1), sizeof(chin1));
printf("第二个字符串长度:%d、占位:%d\n", strlen(chin2), sizeof(chin2));
return 0;
}
//输出
//第一个字符串长度、占位18 19
//第二个字符串长度、占位13 14
#include <stdio.h>
#include <string.h>
int main()
{
char chin1[] = "我是一个学生";
printf("原字符串是: %s\n", chin1);
chin1[3] =65 ; // 字母a的编码
chin1[6] = 7; //改为:chin1[6] = 7;还会响铃!
printf("修改后字符串是: %s\n", chin1);
return 0;
}
#include <stdio.h>
// 二分查找函数,返回目标元素在数组中的索引,如果未找到则返回-1
int binarySearch(int arr[], int size, int target) {
int left = 0;
int right = size - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 防止(left + right)溢出
// 检查中间元素是否是目标值
if (arr[mid] == target) {
return mid;
}
// 如果目标值大于中间元素,忽略左半部分
if (arr[mid] < target) {
left = mid + 1;
} else { // 如果目标值小于中间元素,忽略右半部分
right = mid - 1;
}
}
// 如果未找到目标值,返回-1
return -1;
}
int main() {
int arr[] = {0,2,3,4,6,8,9,11,13};
int size = sizeof(arr) / sizeof(arr[0]);
int target = 11;
int result = binarySearch(arr, size, target);
if (result != -1) {
printf("元素 %d 在数组中的索引为 %d\n", target, result);
} else {
printf("元素 %d 不在数组中\n", target);
}
return 0;
}
#include <stdio.h>
int main() {
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int b[3][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
b[j][i] = a[i][j];
}
}
printf("Transposed matrix:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
printf("%d ", b[i][j]);
}
printf("\n");
}
return 0;
}
<string.h>
。通过以上内容的详细解释和实例分析,初学者可以更加深入地理解数组的概念和运用,掌握数组的修改、查找和排序等基本操作。
因个人习惯和能力所限,该文档内容若存在表述不合理或错误之处,请大家留言多多指正
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明