ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

4.数组dddd

2022-01-12 17:02:16  阅读:127  来源: 互联网

标签:arr int char dddd board 数组 printf


文章目录

一维数组创建和初始化

数组创建

数组:一组相同类型的集合
type_t arr_name [const_n];
C99标准之前是不支持使用变量的,只能是常量
C99中增加了变长数组的概念,允许数组的大小是变量
要求编译器支持C99标准,但常见的编译器(VS)对C99支持不够好
Linux - Centos 7 gcc编译器
image-20220110223102573

char arr3[10];
float arr4[1];
double arr5[20];

数组初始化

int arr1[10] = {1,2,3};
//不完全初始化,剩余元素默认为0
int arr2[] = {1,2,3,4};
int arr3[5] = {1,2,3,4,5};
char arr4[3] = {'a',98, 'c'};
//98 是 'b'的ASCII值
char arr5[] = {'a','b','c'};//数组大小3个字节
char arr6[] = "abc";//还有一个\0
//数组大小4个字节

image-20220110223757978

sizeof与strlen

char arr1[] = {‘a’,‘b’,‘c’};
char arr2[] = “abc”;
arr2中放的是abc’\0’

char arr1[] = { 'a', 'b', 'c' };
//arr1有3个元素,数组的大小是3个字节
printf("%d\n", sizeof(arr1));
printf("%d\n", strlen(arr1));//随机值

char arr2[] = "abc";//a b c \0
//arr2有4个元素,数组的大小是4个字节
printf("%d\n", sizeof(arr2));
printf("%d\n", strlen(arr2));//3

sizeof是操作符,计算变量所占空间大小,任何类型都相同
不在乎内存中是否存在\0
strlen是函数,只针对字符串,计算字符串长度,遇到\0停止
不包括\0
数组如果不初始化,那么就会被赋为随机值,不可控

char acX[] = “abcdefg”;
char acY[] = {‘a’,’b’,’c’,’d’,’e’,’f’,’g’};

数组acX长度大于数组acY长度
但如果问字符串acX长度与字符串acY长度比较 则不能确定
因为acY后面没有\0 strlen遇到\0才会停止故求出来的是随机值

一维数组的使用

[] 下标引用操作符

#include <stdio.h>
int main()
{
int arr[10] = {0};//数组的不完全初始化
   //计算数组的元素个数
   int sz = sizeof(arr)/sizeof(arr[0]);
//对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
int i = 0;//做下标
for(i=0; i<10; i++)//这里写10,好不好?
{
arr[i] = i;
}
//输出数组的内容
for(i=0; i<10; ++i)
{
printf("%d ", arr[i]);
}
return 0;
}
//计算数组元素个数:
int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);
//40 / 4 = 10

一维数组在内存中的存储

int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = &arr[0];
 //打印数组每个元素的地址
int i = 0;
for (i = 0; i < 10; i++)
  {
	printf("&arr[%d] = %p\n", i, &arr[i]);
	printf("%p\n", p + i);//p+i 是数组中arr[i]的地址
	printf("%p ----- %p\n", p + i, &arr[i]);
	printf("%d ", * (p + i));//1 2 3 4 5 6 7 8 9 10
  }
    //整型指针,+1跳过一个整型元素
return 0;
}

image-20220110225156519

0x0c表示十进制的12
p+i 与&arr[i] 等价

二维数组

二维数组创建

int arr[3][4]; //三行四列,每个元素是int型
char arr[3][5];
double arr[2][4];

其实就是数学里的矩阵

二维数组初始化

int arr[3][4] = { {1,2},{3,4},{5,6} };
//不完全初始化
//1 2 0 0
//3 4 0 0
//5 6 0 0
//二维数组初始化不能省略列,行可以省略

image-20220110225843442

#include<stdio.h>
int main()
{
       int arr[3][4] = { {1,2},{2,2},{3,3,3} };
       int arr[][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
       return 0;
}

二维数组使用与存储

#include<stdio.h>
int main()
{
       int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
       int i = 0;
       int j = 0;
       for (i = 0; i < 3; i++)
       {
               for (j = 0; j < 4; j++)
               {
                      printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
               }
       }
       for (i = 0; i < 3; i++)
       {
               for (j = 0; j < 4; j++)
               {
                      printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
               }
       }
       return 0;
}

二维数组理解为一维数组的数组

在内存中是连续储存的,第二行紧跟着第一行
每一行是一个一维数组
以为是这样存储,但实际是连续存储
image-20220110230226081

数组越界

数组的下标如果小于0,或者大于n-1,就是数组越界访了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,
所以程序员写代码时,最好自己做越界的检查。

数组前面后面还是有空间的

#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
   int i = 0;
   for(i=0; i<=10; i++)
  {
       printf("%d\n", arr[i]);//当i等于10的时候,越界访问了
  }
return 0;
}

1
2
3
4
5
6
7
8
9
10
-858993460
数组越界,程序已经错了,但并没有报错,编译器能力有限,有时候识别不出来越界
image-20220111110819712

c语言支持多维数组,但是比较少用

数组作为函数参数

冒泡排序

核心思想:
两两相邻元素进行比较,如果有肯能需要交换

一趟冒泡排序搞定一个数字
让当前待排序数组中的一个元素来到最终应该出现的位置上
10个元素,9躺冒泡排序
image-20220111111334042

#include <stdio.h>
//void bubble_sort(int* arr,int sz) 这样写也可以 
//指针大小是4,不能在函数内算数组元素个数
void bubble_sort(int arr[], int sz)
{
       int i = 0;
       for (i = 0; i < sz - 1; i++)
       {
               //一趟冒泡排序的过程
               int j = 0;
               //一趟冒泡排序比较的对数
               //第二趟比较8对,第三躺比较7对
               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[] = { 3,1,5,2,4,9,0,7,6,8 };
       //设计一个函数对arr数组进行排序-冒泡排序
       int sz = sizeof(arr) / sizeof(arr[0]);
       bubble_sort(arr, sz);//数组名代表的就是数组
       //数组传参,实际上传过去的不是整个数组,传过去的是数组首元素地址
       //避免空间浪费,只需要传首元素地址,就能依据地址找到所有元素
       int i = 0;
       for (i = 0; i < 10; i++)
       {
               printf("%d ", arr[i]);
       }
       return 0;
}

数组名是什么?

补充:

  1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数
    组。
  2. &数组名,取出的是整个数组的地址。&数组名,数组名表示整个数组。
#include <stdio.h>
int main()
{
       int arr[] = { 1,2,3,4,5 };
       printf("%p\n", arr);//00AFF92C
       printf("%p\n", &arr[0]);//00AFF92C
       printf("%p\n", &arr);//00AFF92C
       printf("%d\n", sizeof(arr));//20
       printf("%p\n", arr+1);//00AFF930
       printf("%p\n", &arr[0]+1); //00AFF930
    //跳过4字节
       printf("%p\n", &arr+1); //00AFF940
    //跳过一整个数组,20字节
       //sizeof是例外
       return 0;
}




整个数组地址与数组首元素地址相同
数组名 == 数组首元素地址
数组地址从起始位置开始
数组地址和数组首元素地址意义不一样,值是一样的

游戏

三子棋

image-20220111114226776

test.c 游戏的测试逻辑

#define _CRT_SECURE_NO_WARNINGS 
#include"game.h"
void menu()
{
        printf("******************************\n");
        printf("*********   1.play   *********\n");
        printf("*********   0.exit   ********\n");
        printf("******************************\n");
}

void game()
{
        //数据存储到一个字符的二维数组中,玩家下棋'*' 电脑下棋'#'
        char board[ROW][COL] = { 0 };//数组的内容应该是全部空格
        InitBoard(board,ROW,COL);//初始化棋盘
        DisplayBoard(board,ROW,COL);//打印棋盘
        //下棋
        char ret = 0;
        while (1)
        {
                player_move(board,ROW,COL);
                DisplayBoard(board, ROW, COL);
                ret = is_win(board, ROW, COL);
                if (ret != 'C')//C表示游戏继续
                {
                        break;
                }
                computer_move(board, ROW, COL);
                DisplayBoard(board, ROW, COL);
                if (ret != 'C')
                {
                        break;
                }
        }
        if (ret == '*')
        {
                printf("玩家赢\n");
        }
        else if (ret == '#')
        {
                printf("电脑赢\n");
        }
        else
        {
                printf("平局\n");
        }
}

void test()
{
        int input = 0;
        srand((unsigned int)time(NULL));
        do
        {
                menu();//菜单
                printf("请选择:>");
                scanf("%d", &input);
                switch (input)
                {
                case 1:
                        game();
                        break;
                case 0:
                        printf("退出游戏\n");
                        break;
                default:
                        printf("选择错误\n");
                        break;
                }
        } while (input);
}

int main()
{
        test();
        return 0;
}

game.c 游戏的实现逻辑

image-20220111125407020

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void InitBoard(char board[ROW][COL], int row, int col)
{
        int i = 0;
        int j = 0;
        for (i = 0; i < row; i++)
        {
                for (j = 0; j < col; j++)
                {
                        board[i][j] = ' ';
                }
        }
}

//版本一 只能打印3x3棋盘

/*
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		//数据
		printf(" %c | %c | %c \n", board[i][0], board[i][0], board[i][1]);
		//分隔行(只需打印2个)
		if(i < row - 1)
			printf("---|---|---\n");
	}
}
*/

//版本二 配合宏定义可以灵活修改
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		//数据 把  %c |看成一组数据,但最后一个|不打印
		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)
{
        printf("玩家下棋:>");
        int x = 0;
        int y = 0;
        while (1)
        {
                scanf("%d %d", &x, &y);
                if (x >= 1 && x <= row && y >= 1 && y <= col)//坐标合法性判断
                {
                        if (board[x - 1][y - 1] == ' ')//坐标占用判断
                        {
                                board[x - 1][y - 1] = '*';
                                break;
                        }
                        else
                        {
                                printf("该坐标被占用,请重新输入\n");
                        }
                }
                else
                {
                        printf("坐标非法,请重新输入\n");
                }
        }
}

void computer_move(char board[ROW][COL], int row, int col)
{
        int x = 0;
        int y = 0;
        printf("电脑下棋:>\n");
        while (1)
        {
                x = rand() % ROW;//0 - 2
                y = rand() % COL;//0 - 2
                if (board[x][y] == ' ')
                {
                        board[x][y] = '#';
                        break;
                }
        }
}


int is_full(char board[ROW][COL],int row,int col )
{
        int i = 0;
        int j = 0;
        for (i = 0; i < row; i++)
        {
                for (j = 0; j < col; j++)
                {
                        if (board[i][j] == ' ')
                        {
                                return 0;
                        }
                }
        }
        return 1;//满了
}

//版本1 is_win被写死了,只能判断ROW COL为3的情况
/*char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0;
	
	//三行判断
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
		{
			return board[i][1];
		}
	}
	
	//三列判断
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//判断平局
	if (1 == is_full(board, row, col))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}*/


//版本2 is_win灵活变动
char is_win(char board[ROW][COL], int row, int col)
{
        int i = 0;
        int j = 0;
        int a = 0;
        //判断行
        for (i = 0; i < row; i++)
        {
                a = 0;
                for (j = 0; j < col - 1; j++)
                {
                        if (board[i][j] == board[i][j + 1] && board[i][j] == '*')
                        {
                                a++;
                        }
                        if (board[i][j] == board[i][j + 1] && board[i][j] == '#')
                        {
                                a--;
                        }
                        if (a == col - 1)
                        {
                                return '*';
                        }
                        if (a == -col + 1)
                        {
                                return '#';
                        }
                }
        }

        //判断列
        for (i = 0; i < col; i++)
        {
                a = 0;//a需要清零
                for (j = 0; j < row - 1; j++)
                {
                        if (board[j][i] == board[j + 1][i] && board[j][i] == '*')
                        {
                                a++;
                        }
                        if (board[j][i] == board[j + 1][i] && board[j][i] == '#')
                        {
                                a--;
                        }
                        if (a == row - 1)
                        {
                                return '*';
                        }
                        if (a == -row + 1)
                        {
                                return '#';
                        }
                }
        }

        //判断左对角线
        for (i = 0, j = 0; i < row - 1; i++, j++)
        {
                if (board[i][j] == board[i + 1][j + 1] && board[i][j] == '*')
                {
                        a++;
                }
                if (board[i][j] == board[i + 1][j + 1] && board[i][j] == '#')
                {
                        a--;
                }
                if (a == row - 1)
                {
                        return '*';
                }
                if (a == -row + 1)
                {
                        return '#';
                }
        }

        //判断右对角线
        for (i = 0, j = col - 1; i < row - 1; i++, j--)
        {
                if (board[i][j] == board[i + 1][j - 1] && board[i][j] == '*')
                {
                        a++;
                }
                if (board[i][j] == board[i + 1][j - 1] && board[i][j] == '#')
                {
                        a--;
                }
                if (a == row - 1)
                {
                        return '*';
                }
                if (a == -row + 1)
                {
                        return '#';
                }
        }

        //判断平局
        if (1 == is_full(board, row, col))
        {
                return 'Q';
        }
        //游戏继续
        return 'C';
}

game.h 游戏实现函数的声明

#pragma once
#define ROW 5
#define COL 5
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//初始化棋盘
void InitBoard(char board[ROW][COL],int row,int col);
//打印棋盘
void DisplayBoard(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);

//判断输赢
//玩家赢了 -'*'
//电脑赢了 -'#'
//平局 - 'Q'
//游戏继续 - 'C'
char is_win(char board[ROW][COL], int row, int col);

细节

  1. 棋盘数据打印是把 %c |看成一组数据但最后一个|不打印
    分隔行 把—|看成一组数据但最后一个|不打印且最后一行分隔行也无需打印
  2. 把要用到的头文件及函数都在头文件中声明,这样在.c文件中就只需引用自己创建的头文件,避免了头文件的重复定义
  3. 用时间戳生成随机数的时候,先使用srand函数设置种子,注意srand函数不要放在实现函数的内部,不然会导致随机数生成的很近,srand函数每次游戏只需重新设置一次
    image-20220111120333716

扫雷

9x9 二维数组存储
char board / int board 似乎都行?
先布置累
排查雷
如果用0/1表示有雷无雷 可能会产生冲突
用* #也可以 但符号太多比较麻烦
再弄一个棋盘,放排查出的雷的信息
没排查过的位置放*
所以选char board

防范数组越界,把数组再多开辟一圈就行 11x11数组 用的只是9x9
image-20220111142105836

数字3+‘0’ -> ‘3’

注意不要形成死递归

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
       printf("***********************\n");
       printf("*****  1. play     ****\n");
       printf("*****  0. exit     ****\n");
       printf("***********************\n");
}
void game()
{
       //创建数组
       char mine[ROWS][COLS] = { 0 };//存放布置好的雷信息
       char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
       //初始化mine数组-全字符'0'
       InitBoard(mine,ROWS,COLS,'0');
       //初始化show数组-全字符'*'
       InitBoard(show,ROWS,COLS,'*');
       //打印棋盘,只需打印9x9就行了
       //DisplayBoard(mine, ROW, COL);
       //DisplayBoard(show, ROW, COL);
       //布置雷
       SetMine(mine, ROW, COL);
       DisplayBoard(show, ROW, COL);
       //DisplayBoard(mine, ROW, COL);
       //排雷
       FindMine(mine, show, ROW, COL);
}
void test()
{
       int input = 0;
       srand((unsigned int)time(NULL));
       do
       {
               menu();
               printf("请选择:>\n");
               scanf("%d", &input);
               switch (input)
               {
               case 1:
                      //扫雷
                      game();
                      break;
               case 0:
                      printf("退出游戏\n");
                      break;
               default:
                      printf("选择错误,请重新选择\n");
                      break;
               }
       } while (input);
}
int main()
{
       test();
       return 0;
}

game.h

#pragma once
//头文件包含:符号的声明.函数的声明
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
#define EASY_COUNT 5
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);
//排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
 
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}
 
//棋盘的打印
void DisplayBoard(char board[ROWS][COLS], int row, int col)
    //虽然只打印9*9,但传过去的数组依旧是11*11
{
	//1-9开始
	int i = 0;
	//打印列号
	for (i = 0; i <= col; i++) //i从0开始,避免列号错位(多多尝试就好)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//打印行号
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}
 
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//布置10个雷
	while (count)
	{
		//随机产生的x y坐标是1-9
		int x = rand() % row + 1;
		int y = rand() % col + 1;
 
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}
 

//无需写到头文件,因为不想暴露它 +static保护更加彻底 只能在game.c用
static int get_mine_count(char mine[ROWS][COLS], int x, int y) 
{
	//mine里放的是字符 需要减去'0'
	return mine[x - 1][y] + mine[x - 1][y - 1]
		+ mine[x][y - 1] + mine[x + 1][y - 1]
		+ mine[x + 1][y] + mine[x + 1][y + 1]
		+ mine[x][y + 1] + mine[x - 1][y + 1]
		- 8 * '0';
	//因为设计时11*11 所以x+1 y+1不会越界
}
 
//递归展开一片雷
void Open_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	if (get_mine_count(mine, x, y) == 0)
	{
		show[x][y] = ' ';
		//判断坐标是否越界以及雷是否已经被排除
		if (show[x - 1][y - 1] == '*')
			Open_Mine(mine, show, x - 1, y - 1);
		if (show[x - 1][y] == '*')
			Open_Mine(mine, show, x - 1, y);
		if (show[x - 1][y + 1] == '*')
			Open_Mine(mine, show, x - 1, y + 1);
		if (show[x][y - 1] == '*')
			Open_Mine(mine, show, x, y - 1);
		if (show[x][y + 1] == '*')
			Open_Mine(mine, show, x, y + 1);
		if (show[x + 1][y - 1] == '*')
			Open_Mine(mine, show, x + 1, y - 1);
		if (show[x + 1][y] == '*')
			Open_Mine(mine, show, x + 1, y);
		if (show[x + 1][y + 1] == '*')
			Open_Mine(mine, show, x + 1, y + 1);
	}
	else
	{
		show[x][y] = get_mine_count(mine, x, y) + '0';
	}
}
 
//遍历show,以便判断是否排雷完毕
int Travel(char show[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int win = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '*')
			{
				win++;
			}
		}
	}
	return win;
}
 
 
//排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
    //在mine数组中排雷,信息放到show数组中去
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (1)
	{
		printf("请输入要排查的雷的坐标:>\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)//坐标合法性排查
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, row, col);
				break;
			}
			else
			{
				//计算x y坐标周围有几个雷
				//show 里面放的是字符 数字3 + '0' 就变成'3'
				//字符'0' 48  '2' -> 50 = '0' + 2
				Open_Mine(mine, show, x, y);
				DisplayBoard(show, row, col);
				
			}
		}
		else
		{
			printf("输入坐标非法,请重新输入\n");
		}
		win = Travel(show, row, col);
		if (win == EASY_COUNT)
			break;
	}
	//EASY_COUNT 设置小一点方便检验是否排雷成功
	if (win == EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, row, col);
	}
}

扩展:
image-20220111145200966

练习

1.交换2数组

#include <stdio.h>
int main()
{
       int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
       int arr2[] = { 10,9,8,7,6,5,4,3,2,1 };
       int sz = sizeof(arr1) / sizeof(arr1[0]);
       for (int i = 0; i < sz; i++)
       {
               int tmp = arr1[i];
               arr1[i] = arr2[i];
               arr2[i] = tmp;
       }
       return 0;
}

image-20220111211528782

2.数组操作

创建一个整形数组,完成对数组的操作
实现函数init() 初始化数组为全0
实现print() 打印数组的每个元素
实现reverse() 函数完成数组元素的逆置

#include<stdio.h>
void init(int arr[10], int sz)
{
       int i = 0;
       for (i = 0; i < sz; i++)
       {
               arr[i] = 0;
       }
}
void print(int arr[10], int sz)
{
       int i = 0;
       for (i = 0; i < sz; i++)
       {
               printf("%d ", arr[i]);
       }
       printf("\n");
}
void reverse(int arr[10], int sz)
{
       int left = 0;
       int right = sz - 1;
       while (left < right)
       {
               int tmp = arr[left];
               arr[left] = arr[right];
               arr[right] = tmp;
               left++;
               right--;
       }
}
int main()
{
       int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
       int sz = sizeof(arr) / sizeof(arr[0]);
       print(arr, sz);
       reverse(arr, sz);
       print(arr, sz);
       init(arr, sz);
       print(arr, sz);
       return 0;
}

3.字符串逆序

编写一个函数 reverse_string(char* string)(递归实现)
实现:将参数字符串中的字符反向排列,不是逆序打印。
要求:不能使用C函数库中的字符串操作函数。
比如 :
char arr[] = “abcdef”;
逆序之后数组的内容变成:fedcba

递归实现:

image-20220111203930683

#include <string.h>

int my_strlen(char* s)
{
	int count = 0;
	while (*s != '\0')
	{
		count++;
		s++;
	}
	return count;
}


//[a b c d e f g \0]
//递归版本
void reverse_string(char* arr)
{
	int len = my_strlen(arr);
	char tmp = *arr;//a
	*arr = *(arr + len - 1);//找到了g
	*(arr + len - 1) = '\0';//先把g的内容赋值为\0才能识别为字符串
	if(my_strlen(arr+1)>1)//递归必须要有结束条件
		reverse_string(arr+1);//arr+1找到b的地址
	*(arr + len - 1) = tmp;//再把a放回到g的位置
}


//参数用指针的形式
void reverse_string(char* str)
{
	char* left = str;//a的地址
	char* right = str + my_strlen(str) - 1;
	while (left<right)
	{
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}

//参数是数组的形式
void reverse_string(char arr[])
{
	int left = 0;
	int right = my_strlen(arr)-1;

	//交换
	while (left<right)
	{
		char tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;
		left++;
		right--;
	}
}


int main()
{
	char arr[] = "abcdefg";
	reverse_string(arr);
	printf("%s\n", arr);//fedcba
	return 0;
}

image-20220111203156679

4.计算每位数之和

//写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
//例如,调用DigitSum(1729),则应该返回1 + 7 + 2 + 9,它的和是19
//输入:1729,输出:19

int DigitSum(size_t n)
{
	if (n <= 9)
		return n;
	else
		return DigitSum(n / 10) + n % 10;
}

int main()
{
	size_t num = 0;
	scanf("%u", &num);
	int ret = DigitSum(num);
	printf("%d\n", ret);

	return 0;
}

5.求n^k

double Pow(int n, int k)
{
	if (k == 0)
		return 1;
	else if (k > 0)
		return n * Pow(n, k - 1);
	else
		return 1.0 / Pow(n, -k);
}

int main()
{
	int n = 0;
	int k = 0;
	scanf("%d %d", &n, &k);

	double ret = Pow(n, k);

	printf("%lf\n", ret);

	return 0;
}

要注意考虑k<0的情况

标签:arr,int,char,dddd,board,数组,printf
来源: https://blog.csdn.net/a2076188013/article/details/122457536

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有