C语言数组和字符串笔记

C语言数组和字符串笔记

1. 数组及其相关概念

1.1 为什么需要使用数组?

数组是一个有序的、类型相同的数据集合。这些数据被称为数组的元素。每个数组都有一个名字,数组名代表数组的起始地址。数组的元素通过索引或下标访问,索引从0开始。

1.2 数组的定义

在使用数组之前,必须先定义数组。数组的定义包括以下几个部分:

  • 存储类型(如 int, char 等)
  • 数据类型(数组元素的类型)
  • 数组名(数组的标识符)
  • 数组大小(数组元素的个数)
数组定义语法:
存储类型 数据类型 数组名[数组长度];

例如:

int player[11];
数组的规范:
  • 数组的元素必须具有相同的数据类型。
  • 数组的元素可以通过下标访问,下标是从0开始的。
  • 数组的下标可以使用整型表达式,如 array[3+2]

2. 数组的存储方式

2.1 一维数组的存放方式

在内存中,一维数组的元素是连续存放的,每个元素占用的字节数与数据类型的字节数相同。

例如,定义一个浮点型数组 float mark[100];,每个元素占用4个字节。数组的存储形式如下:

text 低地址         高地址
mark[0]  mark[1]  mark[2] ... mark[99]

2.2 数组初始化

  • 数组初始化是在定义时给数组的元素赋初值。
  • 可以给部分元素赋值,未赋值的元素将自动初始化为0。
初始化语法:
类型 数组名[常量表达式] = {1,2, ..., 值n};
示例:
int ary[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

2.3 初始化的规则

  • 如果初始化数据个数少于数组长度,未初始化的元素会被自动赋值为0。
  • 如果初始化数据个数多于数组长度,编译器会报错。
  • 数组长度可以隐式指定。
示例:
int ary1[] = {1, 2, 3, 4, 5};  // 数组长度自动为5

3. 二维数组

3.1 二维数组的定义

二维数组可以看作是由多个一维数组组成的数组,通常表示一个矩阵或表格。二维数组的声明如下:

数据类型 数组名[行数][列数];
示例:
int temp[4][3];  // 定义一个 4 行 3 列的二维数组

3.2 二维数组初始化

可以使用不同的方式初始化二维数组:

示例:
int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};

3.3 二维数组的访问

二维数组的元素可以通过行和列的下标访问。例如,访问 a[1][2] 就是访问二维数组中第二行第三列的元素。

3.4 矩阵转置示例

#include <stdio.h>
#define MAX_ROW 2
#define MAX_COL 3void main() {int a[MAX_ROW][MAX_COL] = {{1, 2, 3}, {4, 5, 6}};int b[MAX_COL][MAX_ROW];// 矩阵转置for (int i = 0; i < MAX_ROW; i++) {for (int j = 0; j < MAX_COL; j++) {b[j][i] = a[i][j];}}// 输出转置后的矩阵for (int i = 0; i < MAX_COL; i++) {for (int j = 0; j < MAX_ROW; j++) {printf("%4d", b[i][j]);}putchar('\n');}
}

4. 字符数组和字符串

4.1 字符串常量

字符串常量是由双引号括起来的字符序列。例如,字符串 "hello" 在内存中的存储方式如下:

h e l l o \0

其中,'\0' 是字符串的结束符。

4.2 字符数组与字符串

C语言没有专门的字符串类型,字符串是通过字符数组来实现的。字符数组用于存储一个字符串,二维字符数组用于存储多个字符串。

字符串数组定义示例:
char str[10];  // 声明一个字符数组,最多存储9个字符+结束符

4.3 字符串的初始化

  • 字符串初始化时,C语言会自动在字符串末尾添加一个 '\0' 作为结束符。
示例:
char str[6] = "hello";  // 自动在末尾加上 '\0'

4.4 字符串的使用

字符数组也可以像普通数组一样使用,通过下标访问和修改字符数组的元素。

char str[6] = "hello";
str[0] = 'H';  // 修改字符串的第一个字符

5. 字符串输入输出操作

5.1 输入字符串

使用 scanf 函数来输入字符串,使用 %s 格式说明符:

char str[100];
scanf("%s", str);  // 输入字符串

5.2 输出字符串

使用 printf 函数输出字符串,使用 %s 格式说明符:

printf("%s", str);  // 输出字符串

5.3 getsputs 函数

  • gets:用于从标准输入获取字符串,直到遇到换行符。
  • puts:用于输出字符串,并自动换行。

5.4 sprintf 函数

sprintf 将格式化的字符串输出到字符数组中。常用于将数值转换为字符串。

char buffer[100];
int num = 10;
sprintf(buffer, "Number is: %d", num);  // 将整数格式化为字符串

6. 字符串处理函数

6.1 strlen 函数

用于计算字符串的长度,不包括字符串的结束符 '\0'

int len = strlen(str);

6.2 strcpy 函数

将一个字符串复制到另一个字符串。

strcpy(dest, source);

6.3 strcat 函数

将两个字符串连接起来。

strcat(dest, source);

6.4 strcmp 函数

比较两个字符串,返回值说明:

  • 返回值小于0:str1 < str2
  • 返回值等于0:str1 == str2
  • 返回值大于0:str1 > str2
int result = strcmp(str1, str2);

6.5 strchrstrstr 函数

  • strchr:查找一个字符在字符串中第一次出现的位置。
  • strstr:查找一个子字符串在另一个字符串中的位置。
 char *ptr = strchr(str, 'a');  // 查找字符 'a'
char *ptr = strstr(str, "abc");  // 查找子字符串 "abc"

7. C语言中的字符函数

7.1 头文件 ctype.h

  • isalnum:检查是否为字母或数字。
  • isalpha:检查是否为字母。
  • isdigit:检查是否为数字。
  • islower:检查是否为小写字母。
  • isupper:检查是否为大写字母。
  • isspace:检查是否为空白字符。

8. 类型转换函数

8.1 头文件 stdlib.h

  • atof:将字符串转换为浮点型。
  • atoi:将字符串转换为整型。
  • atol:将字符串转换为长整型。
double num = atof("3.14");
int x = atoi("123");
long y = atol("123456");

9. C语言数组案例

第一个案例是经典冒泡排序,第二个 ==“小”==案例是简易五子棋,但是用各种符号设置棋盘,下棋时,棋盘总是会发生改动,我尝试修改多次,都无法解决这个问题,最终替换掉了所有的符号,只用“ . ” 来显示,打印棋盘时加入判断,每落一次棋子,其实相当于打印了一次棋盘,将原有的“ . ”替换为白子或者黑子。可以完美解决棋盘动的问题,当然,也尝试加入边框,但是这个时候就不是下在交叉线上了,而是框里。本来想着随机落子就行,后来想弄高级一点,就查了查资料,用了Alpha-Beta算法来优化计算机落子。(反正用鸡皮提改了又改,最后反正能跑了)。拒不承认输了一次。

修改前:

img

img

img

解决后:

img

img

9.1 五子棋源码

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>#define SIZE 15  // 棋盘大小
#define DEPTH 4  // 搜索深度
#define EMPTY 0
#define BLACK 1
#define WHITE 2// 函数声明
void printBoard();
int isValidPos(int x, int y);
int evaluatePosition(int x, int y, int player);
void findBestMove(int player, int *bestX, int *bestY);
void playerMove(int player);
void aiMove(int player);
int checkWin(int x, int y, int player);
int checkDraw();
void playGomoku();int lastMoveX = -1, lastMoveY = -1;  // 全局变量,用于记录最后落子位置// 方向数组
const int dx[] = {1, 0, 1, 1};
const int dy[] = {0, 1, 1, -1};// 棋盘状态
int board[SIZE][SIZE] = {0};int main() 
{int choice;while(1) {printf("\n==== 主菜单 ====\n");printf("1. 数组排序\n");printf("2. 五子棋游戏\n");printf("0. 退出程序\n");printf("请输入选择: ");scanf("%d",&choice);switch(choice) {case 1:bubbleSort();break;case 2:playGomoku();break;case 0:printf("程序已退出\n");return 0;default:printf("无效选择,请重试\n");}}return 0;
}void bubbleSort()
{int arr[5];int count = 0;int temp;int i;int j;char ch;  // 用于清理缓冲区printf("请输入5个整数:\n");for(i = 0;i < 5;i++){printf("请输入第%d个数: ", i + 1); if(scanf("%d", &arr[i]) == 1){count++;}else{printf("输入有误!程序结束!\n");while((ch = getchar()) != '\n');return;}}for(i = 0; i < 5; i++){for(j = 0; j < 4 - i; j++){if(arr[j] > arr[j+1]){temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;				}}}printf("\n从小到大排序后的结果:\n");for(j = 0;j < 5; j++){printf("%d ", arr[j]);}	}// 打印棋盘
void printBoard() {int i, j;// 打印多个换行来分隔printf("\n\n");// 打印列标号,确保与点位对齐printf("     ");  // 缩进5个空格,与行号对齐for(i = 1; i <= SIZE; i++) {printf("%2d  ", i);  // 统一使用2字符宽度,后加2空格}printf("\n\n");// 打印主棋盘for(i = 0; i < SIZE; i++) {// 打印行号,保持对齐printf("%2d   ", i + 1);  // 统一使用2字符宽度,后加3空格// 打印每一行的内容for(j = 0; j < SIZE; j++) {if(board[i][j] == BLACK)printf("●  ");    // 黑子后加2个空格else if(board[i][j] == WHITE)printf("○  ");    // 白子后加2个空格elseprintf("·  ");    // 空位点后加2个空格}printf("\n\n");  // 每行后打印一个空行}printf("\n请输入落子位置 (行 列): ");
}// 检查位置是否有效
int isValidPos(int x, int y) {return x >= 0 && x < SIZE && y >= 0 && y < SIZE;
}// 简化的位置评估函数
int evaluatePosition(int x, int y, int player) {int score = 0;int opponent = 3 - player;int d, count, empty, block;int nx, ny;// 检查四个方向for(d = 0; d < 4; d++) {count = 1;empty = 0;block = 0;// 正向检查nx = x + dx[d];ny = y + dy[d];while(isValidPos(nx, ny)) {if(board[nx][ny] == player) count++;else if(board[nx][ny] == EMPTY) {empty++;break;}else {block++;break;}nx += dx[d];ny += dy[d];}// 反向检查nx = x - dx[d];ny = y - dy[d];while(isValidPos(nx, ny)) {if(board[nx][ny] == player) count++;else if(board[nx][ny] == EMPTY) {empty++;break;}else {block++;break;}nx -= dx[d];ny -= dy[d];}// 评分规则if(count >= 5) score += 100000;else if(count == 4) {if(empty == 2) score += 10000;  // 活四else if(empty == 1) score += 1000;  // 冲四}else if(count == 3) {if(empty == 2) score += 1000;  // 活三else if(empty == 1) score += 100;  // 眠三}}return score;
}// 找出最佳落子位置
void findBestMove(int player, int *bestX, int *bestY) {int maxScore = -1;int i, j, di, dj, ni, nj;int hasNeighbor;int score;*bestX = SIZE/2;*bestY = SIZE/2;// 只考虑已有棋子周围的空位for(i = 0; i < SIZE; i++) {for(j = 0; j < SIZE; j++) {if(board[i][j] != EMPTY) continue;// 检查是否有相邻的棋子hasNeighbor = 0;for(di = -1; di <= 1; di++) {for(dj = -1; dj <= 1; dj++) {if(di == 0 && dj == 0) continue;ni = i + di;nj = j + dj;if(isValidPos(ni, nj) && board[ni][nj] != EMPTY) {hasNeighbor = 1;break;}}if(hasNeighbor) break;}if(!hasNeighbor) continue;score = evaluatePosition(i, j, player);// 考虑防守对手score += evaluatePosition(i, j, 3-player) * 0.8;if(score > maxScore) {maxScore = score;*bestX = i;*bestY = j;}}}
}// 检查平局
int checkDraw() {int i, j;for(i = 0; i < SIZE; i++) {for(j = 0; j < SIZE; j++) {if(board[i][j] == EMPTY) return 0;}}return 1;
}// 玩家落子
void playerMove(int player) {int x, y;while(1) {printf("请输入落子位置 (行 列): ");scanf("%d %d", &x, &y);x--; y--;  // 转换为数组索引if(isValidPos(x, y) && board[x][y] == EMPTY) {board[x][y] = player;lastMoveX = x;    // 记录最后落子位置lastMoveY = y;break;}printf("无效位置,请重试!\n");}
}// 电脑落子
void aiMove(int player) {printf("电脑正在思考...\n");int bestX, bestY;findBestMove(player, &bestX, &bestY);board[bestX][bestY] = player;lastMoveX = bestX;    // 记录最后落子位置lastMoveY = bestY;printf("电脑落子位置:%d %d\n", bestX + 1, bestY + 1);
}// 检查获胜
int checkWin(int x, int y, int player) {if(x < 0 || y < 0) return 0;  // 添加边界检查int d, count;int nx, ny;for(d = 0; d < 4; d++) {count = 1;// 正向检查nx = x + dx[d];ny = y + dy[d];while(isValidPos(nx, ny) && board[nx][ny] == player) {count++;nx += dx[d];ny += dy[d];}// 反向检查nx = x - dx[d];ny = y - dy[d];while(isValidPos(nx, ny) && board[nx][ny] == player) {count++;nx -= dx[d];ny -= dy[d];}if(count >= 5) return 1;}return 0;
}// 游戏主循环
void playGomoku() {int currentPlayer = BLACK;int gameOver = 0;int i, j;// 重置最后落子位置lastMoveX = -1;lastMoveY = -1;// 初始化棋盘for(i = 0; i < SIZE; i++) {for(j = 0; j < SIZE; j++) {board[i][j] = EMPTY;}}printf("\n=== 五子棋游戏 ===\n");printf("您执黑子(●),电脑执白子(○)\n");printf("请输入落子位置的行号和列号(1-%d)\n\n", SIZE);while(!gameOver) {printBoard();if(currentPlayer == BLACK) {playerMove(currentPlayer);} else {aiMove(currentPlayer);}// 立即检查胜负if(checkWin(lastMoveX, lastMoveY, currentPlayer)) {printBoard();printf("\n%s胜利!\n", currentPlayer == BLACK ? "玩家" : "电脑");gameOver = 1;continue;  // 直接结束游戏}if(checkDraw()) {printBoard();printf("\n游戏平局!\n");gameOver = 1;continue;}currentPlayer = 3 - currentPlayer;  // 切换玩家}// 游戏结束后等待用户确认printf("\n按Enter键返回主菜单...");getchar();getchar();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/63982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

双目摄像头标定方法

打开matlab 找到这个标定 将双目左右目拍的图像上传&#xff08;左右目最好不少于20张&#xff09; 等待即可 此时已经完成标定&#xff0c;左下角为反投影误差&#xff0c;右边为外参可视化 把这些误差大的删除即可。 点击导出 此时回到主页面&#xff0c;即可看到成功导出 Ca…

数据结构开始——时间复杂度和空间复杂度知识点笔记总结

好了&#xff0c;经过了漫长的时间学习c语言语法知识&#xff0c;现在我们到了数据结构的学习。 首先&#xff0c;我们得思考一下 什么是数据结构&#xff1f; 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素…

什么是MMD Maximum Mean Discrepancy 最大均值差异?

9多次在迁移学习看到了&#xff0c;居然还是Bernhard Schlkopf大佬的论文&#xff0c;仔细看看。 一.什么是MMD&#xff1f; 1. MMD要做什么&#xff1f; 判断两个样本&#xff08;族&#xff09;是不是来自于同一分布 2.怎么做&#xff1f;&#xff08;直观上&#xff09;…

电梯内电动车识别数据集,可准确识别电梯内是否有电动车 支持YOLO,COCO,VOC三种格式的标注 7111张图片

电梯内电动车识别数据集&#xff0c;可识别电梯内是否有电动车 支持YOLO&#xff0c;COCO&#xff0c;VOC三种格式的标注 7111张图片 7111总图像数 数据集分割 训练组 74&#xff05; 5291图片 有效集 16% 1168图片 测试集 9&#xff05; 652…

Collection接口

目录 一. Collection基本介绍 二. Collection中的方法及其使用 1. 添加元素 (1) 添加单个元素 (2) 添加另一集合中的所有元素 2. 删除元素 (1) 删除单个元素 (2) 删除某个集合中包含在其他集合中的元素 (3) 保留两个集合中的交集部分, 删除其他元素. 3. 遍历元素 (1) …

Mybatis Plus 3.0 快速入门

1、简介 MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 2、创建并初始化数据库 2.1、创建数据库 mybatis_plus 2.2、创建 User 表 其表结构如下: idnameageemail1Jone18test1@baomidou.com2Jack…

Verilog实现图像处理的行缓存Line Buffer

在图像处理中&#xff0c;难免会遇到对图像进行卷积或者模板的局部处理&#xff0c;例如ISP中的一些算法&#xff0c;很大部分都需要一个窗口&#xff0c;在实时视频处理中&#xff0c;可以利用行缓存Line buffer可以暂存几行数据&#xff0c;然后同时输出每行中的对应列的像素…

【银河麒麟高级服务器操作系统】有关dd及cp测试差异的现象分析详解

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn dd现象 使用银河麒麟高级服务器操作系统执行两次…

ORACLE逗号分隔的字符串字段,关联表查询

使用场景如下&#xff1a; oracle12 以前的写法&#xff1a; selectt.pro_ids,wm_concat(t1.name) pro_names from info t,product t1 where instr(,||t.pro_ids|| ,,,|| t1.id|| ,) > 0 group by pro_ids oracle12 以后的写法&#xff1a; selectt.pro_ids,listagg(DIS…

记录2024-leetcode-字符串DP

10. 正则表达式匹配 - 力扣&#xff08;LeetCode&#xff09;

微信开发者工具(小程序)的版本管理,Git Push 和 Pull

微信开发者工具&#xff08;小程序&#xff09;的版本管理&#xff0c;Git Push 和 Pull 一、设置 第一次用微信开发者工具自带的版本管理的拉取和推送功能&#xff0c;稍稍的研究了下。 1、首先要先设置 “用户”&#xff0c;名字和邮箱&#xff0c;不一定要真名&#xff0c…

2020-12-07 光棍数

由光棍数的特征可推导其商的个位数不存在偶数且只有1、3、7、9这4个数。一个数可匹配多个光棍数且必定是中间隔着0的循环数。 void 光棍数(int n) {//缘由http://ask.csdn.net/questions/3444069 做乘法运行时间超长int w 0; long long x 111111111111111, j 0;//j x*n;/…

【Linux系统】—— 初识 shell 与 Linux 中的用户

【Linux系统】—— 初识shell 与 Linux 中的用户 1 Xshell 运行原理1.1 命令行的组成1.2 外壳程序 2 Linux中的用户2.1 两种用户2.2 创建普通用户2.3 用户切换2.3.1 普通->超级2.3.2 超级->普通 3 指令的短暂提权3.1 为什么要提权3.2 sudo 指令3.3 人人都能提权吗 1 Xshe…

.NET平台使用C#设置Excel单元格数值格式

设置Excel单元格的数字格式是创建、修改和格式化Excel文档的关键步骤之一&#xff0c;它不仅确保了数据的正确表示&#xff0c;还能够增强数据的可读性和专业性。正确的数字格式可以帮助用户更直观地理解数值的意义&#xff0c;减少误解&#xff0c;并且对于自动化报告生成、财…

Android显示系统(10)- SurfaceFlinger内部结构

一、前言: 之前讲述了native层如何使用SurfaceFlinger,我们只是看到了简单的API调用,从本文开始,我们逐步进行SurfaceFlinger内部结构的分析。话不多说,莱茨狗~ 二、类图: 2.1、总体架构: 先看下SurfaceFlinger的关键成员和我们BootAnimation侧关键成员如何对应起来…

深度学习中的多通道卷积与偏置过程详解

目录 ​编辑 多通道卷积的深入理解 &#x1f50d; 卷积核的多维特性 &#x1f30c; 卷积操作的细节 &#x1f527; 多通道卷积的优势 &#x1f31f; 偏置过程的深入理解 &#x1f3af; 偏置的两种实现方式 &#x1f6e0;️ 偏置的作用与重要性 &#x1f308; 多通道卷…

易语言鼠标轨迹算法(游戏防检测算法)

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

【蓝桥杯选拔赛真题93】Scratch青蛙过河 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析

目录 Scratch青蛙过河 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 Scratc…

手机实时提取SIM卡打电话的信令声音--社会价值(一、方案解决了什么问题)

手机实时提取SIM卡打电话的信令声音 --社会价值(一、方案解决了什么问题) 一、前言 这段时间&#xff0c;我们在技术范围之外陷入了一个自证或者说下定义的怪圈&#xff0c;即要怎么样去介绍或者描述&#xff1a;我们是一个什么样的产品。它在当前这个世界上&#xff0c;处于…

【LeetCode】每日一题 2024_12_13 K 次乘运算后的最终数组 I(暴力)

前言 每天和你一起刷 LeetCode 每日一题~ 小聊两句 1、今天是 12.13 南京大屠杀国家公祭日。铭记历史&#xff0c;勿忘国耻。 2、今天早上去看了 TGA 年度游戏颁奖&#xff0c;小机器人拿下了年度最佳游戏&#xff0c;所有人都震惊了&#xff0c;大伙纷纷问到&#xff0c;谁…