【C语言】基础篇三、数组 您所在的位置:网站首页 二维数组的排序函数怎么用 【C语言】基础篇三、数组

【C语言】基础篇三、数组

2023-07-06 03:00| 来源: 网络整理| 查看: 265

1、一维数组 创建与初始化

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

数组的创建方式:

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

数组的初始化:

int arr[10];//不初始化,内容为随机值 int a;//局部变量未初始化,内容也是随机值 //全局变量,静态变量(static int b)则默认是0 打印上面的值时,可能无法打印(arr成功,a失败) int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };//完全初始化 int arr2[10] = { 1,2,3,4 };//不完全初始化,其余元素默认为0 //但不能多放 //数组初始化时可以不指定大小,程序会根据初始化的内容确定数组大小: int arr3[] = { 1,2,3,4 }; 创建数组能不能用变量? int n = 10; int arr[n];//C99中引入了变长数组的概念,允许数组的大小用变量来指定, //如果编译器不支持C99中的变长数组,那就不能使用,VS2022不支持 变长数组可以使数组可大可小:(动态内存管理也可以实现) int n = 10; scanf("%d", &n); int arr[n]; C++(.cpp文件)中const修饰的常量就叫常量,C(.c文件)中为常变量 char ch1[] = { 'a', 98, 'c' };//b的ASCII码值可以直接填入代表b char ch2[] = { 'a', 'b', 'c' };//放入3个字符 a b c char ch3[5] = { 'a', 'b', 'c' };//多放2个\0 char ch4[] = "abc";//放入4个字符 a b c \0 char ch5[5] = "abc";//多放1个\0 错误:四个字符放在三个字符的数组中 char arr[3] = "abc";//还有一个\0 编译器有时不能报出所有的错误,所以不报错不代表没有错 改正: char arr[4] = "abc"; 使用

下标引用操作符:[]

int arr[100] = { 1,2,3,4,5,6 }; printf("%d\n", arr[4]);//下标引用操作符有两个操作数:arr(数组名)、4(下标) printf("%d\n", sizeof(arr));//打印400,因为100个整型元素 printf("%d\n", sizeof(arr[0]));//1个字符4字节 int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素个数的写法 //写代码来赋值1~100 int i = 0; //赋值 for (i = 0; i < 100; i++)//100建议替换成sz { arr[i] = i + 1; } //打印 for (i = 0; i < 100; i++)//100建议替换成sz { printf("%d ", arr[i]); } //可以把赋值打印合成一个 //一维数组在内存中的存储 int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; //打印数组的每个元素的地址 int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); for(i = 0; i < sz; i++) { printf("&arr[%d] = %p\n", i, &arr[i]); } return 0; }

发现:两元素之间的地址差4,因为1个整型元素的大小是4个字节

说明:

一维数组在内存中是连续存放的随着数组下标的增长,地址是由低到高变化的 int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); int* p = &arr[0]; for(i = 0; i < sz; i++) { printf("&arr[%d] = %p %p\n", i, &arr[i], p+i); } return 0; }

左&arr[i] 右p+i

第一个元素时,i=0

第二个元素时,i=1,p+1相当于跳了4个字节,因为p是一个整型指针,+1应该跳过一个整型(字节)

char* p,p+1相当于跳过一个字符,跳了1个字节

2、二维数组 创建 int arr[3][4];//3行4列的整型数据 char arr[3][5]; double arr[2][4]; 初始化

行可以省略,列不能省略:

//完全初始化 int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} }; int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };//挨个放 //不完全初始化,未被初始化元素默认初始化为0 int arr[3][5] = { {1,2,3},{4,5,6},{7,8,9} }; int arr[3][5] = { 1,2,3,4,5,6,7,8,9 }; //省略行数 int arr[][5] = { {1,2,3},{4,5,6},{7,8,9} };//自动补为3行 int arr[][5] = { 1,2,3,4,5,6,7,8,9 };//自动补为2行 //省略列数(和行数) int arr[3][] = { 1,2,3,4,5,6,7,8,9 };//错误 int arr[][] = { 1,2,3,4,5,6,7,8,9 };//错误 使用

行和列的下标都从0开始

#define _CRT_SECURE_NO_WARNINGS 1 #include int main() { int arr[][5] = { {1,2},{3,4},{5,6} }; int i = 0; for (i = 0; i < 3; i++)//行 //或i < sizeof(arr) / sizeof(arr[0]),整个数组大小 / 数组第一行大小 { int j = 0; for (j = 0; j < 5; j++)//列 //或j < sizeof(arr[0]) / sizeof(arr[0][0]),数组第一行大小 / 第一行第一个元素大小 { printf("%d ", arr[i][j]);//打印一行 } printf("\n");//换行 } return 0; } 内存中的存储

二维数组在内存中也是连续存放的

#define _CRT_SECURE_NO_WARNINGS 1 #include int main() { int arr[3][5] = { {1,2},{3,4},{5,6} }; int i = 0; for (i = 0; i < 3; i++) { int j = 0; for (j = 0; j < 5; j++) { printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);//打印地址 } } return 0; }

C语言支持多维数组,多维数组可以理解为一维数组的数组(的数组…),常用一维、二维数组

可以理解为:第一行数组名为arr[0],第二行数组名为arr[1],第三行数组名为arr[2]

三维数组 int arr[3][4][5];//三个维度,类似长宽高,第一维范围0~2,第二维范围0~3,第三维范围0~4 3、数组越界

数组的下标是有范围限制的,如果超出下标范围,会出错,但是编译器不一定报错,所以最好自己做越界的检查

#define _CRT_SECURE_NO_WARNINGS 1 #include int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int i = 0; for (i = 0; i arr[j + 1]) { //交换 int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } int main() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; //写一个冒泡排序的函数,来排序arr数组的内容 bubble_sort(arr);//不能写&arr int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }

运行后结果为8 9 7 6 5 4 3 2 1 0,不符合预期

调试后发现:第8行sz期望值为10,但监视发现是1

数组名是什么 #include int main() { int arr[10] = { 5,4,3,2,1 }; printf("%p\n", arr); printf("%p\n", &arr[0]); printf("%d\n", *arr); //输出结果 return 0; }

结论:数组名是首元素的地址(有两个例外)

sizeof(数组名),数组名不是首元素的地址,数组名表示整个数组,计算的是整个数组的大小&数组名,数组名不是首元素的地址,数组名表示整个数组,取出的是整个数组的地址 例外1: int arr[10] = { 0 }; printf("%d\n", sizeof(arr));//(若为地址,结果应该是4/8) 例外2: int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("%p\n", arr); printf("%p\n", arr+1);//地址+4 printf("\n"); printf("%p\n", &arr[0]); printf("%p\n", &arr[0]+1);//地址+4 printf("\n"); printf("%p\n", &arr);//发现打印的是首元素地址 printf("%p\n", &arr+1);//地址+40 printf("%d\n", sizeof(&arr));//输出4/8 printf("%d\n", sizeof(arr));//输出40(无论32/64) 自测 int a = 0; printf("%p\n", &a); printf("%d\n", sizeof(&a)); 冒泡排序函数的正确设计

把int sz = sizeof(arr) / sizeof(arr[0]);从冒泡函数放到主函数中,再把sz传参给冒泡函数

#define _CRT_SECURE_NO_WARNINGS 1 #include void bubble_sort(int arr[], int sz)//int arr[]本质上是int* arr,是个指针,不是数组 //数组传参写成数组,更易理解,只是形式而已,可以写成int* arr,但是不能写成int arr { int i = 0;//趟数,与元素个数有关系,等于元素个数减一 for (i = 0; i < sz - 1; i++) { //每一趟冒泡排序过程 int j = 0; for (j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { //交换 int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } int main() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; int sz = sizeof(arr) / sizeof(arr[0]); //写一个冒泡排序的函数,来排序arr数组的内容 bubble_sort(arr, sz);//不能写&arr int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }

优化:若一趟冒泡排序没有发生交换,则已经有序,在冒泡排序添加flag去判断是否有序

#define _CRT_SECURE_NO_WARNINGS 1 #include void bubble_sort(int arr[], int sz)//int arr[]本质上是int* arr,是个指针,不是数组 //数组传参写成数组,更易理解,只是形式而已,可以写成int* arr,但是不能写成int arr { int i = 0;//趟数,与元素个数有关系,等于元素个数减一 for (i = 0; i < sz - 1; i++) { int flag = 1;//假设已经有序 //每一趟冒泡排序过程 int j = 0; for (j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { flag = 0;//发生交换就无序 int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } if (1 == flag) { break; } } } int main() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; int sz = sizeof(arr) / sizeof(arr[0]); //写一个冒泡排序的函数,来排序arr数组的内容 bubble_sort(arr, sz);//不能写&arr int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; } 5、三子棋 //game.h文件 #pragma once //函数声明,符号定义 #include #include #include #define ROW 3 #define COL 3 //初始化棋盘 void init_board(char board[ROW][COL], int row, int col); //打印棋盘 void print_board(char board[ROW][COL], int row, int col); //玩家下棋 void player_move(char board[ROW][COL], int row, int col); //电脑下棋 void computer_move(char board[ROW][COL], int row, int col); //判断输赢 char if_win(char board[ROW][COL], int row, int col); //game.c文件 #define _CRT_SECURE_NO_WARNINGS 1 //游戏的实现 #include "game.h" void init_board(char board[ROW][COL], int row, int col)//row - 行;col - 列 { int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { board[i][j] = ' '; } } } void print_board(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { int j = 0; //打印数据 for (j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j < col - 1) printf("|"); } printf("\n"); //打印分割行 if (i < row - 1) for (j = 0; j < col; j++) { printf("---"); if (j < col - 1) printf("|"); } printf("\n"); } } void player_move(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("玩家下棋\n"); printf("请输入坐标(行/列):>"); scanf("%d%d", &x, &y); if (x >= 1 && x = 1 && y


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有