趣味C语言
Posted 专业include*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了趣味C语言相关的知识,希望对你有一定的参考价值。
一、矩阵转置
分析:
(1)先分别输入数组的行数和列数;
(2)逐个输入数组中的元素,元素个数为刚刚输入的行数与列数的乘积;
(3)通过for循环进行转置;
(4)最终将统计出的结果输出到屏幕上;
代码实现:
#include <stdio.h>
int main()
{
int i, j, row, column; //定义表示数组行列的变量
int a[10][10], b[10][10]; //定义二维数组
printf("Please input the number of rows (<10)\\n");
scanf("%d", &row); //输入行数
printf("please input the number of columns(<10)\\n");
scanf("%d", &column); //输入列数
printf("Please input the elements of the array\\n");
for (i = 0; i < row; i++) //控制输出的行数
{
for (j = 0; j < column; j++) //控制输出的列数
{
scanf("%d", &a[i][j]); //输入数组中的元素
}
}
//矩阵转置之前
printf("array a:\\n"); //将输入的数据以二维数组的形式输出
for (i = 0; i < row; i++) //控制输出的行数
{
for (j = 0; j < column; j++) //控制输出的列数
{
printf("\\t%d", a[i][j]); //输出元素
}
printf("\\n"); //每输出一行要在末尾换行
}
//矩阵转置过程
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
b[j][i] = a[i][j]; //将a数组的i行j列元素赋给b数组的j行i列元素
}
}
//矩阵转置之后
printf("array b:\\n"); //将互换后的b数组输出
for (i = 0; i < column; i++) //b数组行数最大值为a数组列数
{
for (j = 0; j < row; j++) //b数组列数最大值为a数组行数
{
printf("\\t%d", b[i][j]); //输出b数组元素
}
printf("\\n"); //每输出一行要在末尾换行
}
return 0;
}
运行截图:
二、猜宝游戏
描述:初始时,甲的左手握着一枚硬币,游戏开始后,甲进行有限次或真或假的交换,最后由乙来猜测这两只手中是否有硬币。
分析:
(1)使用基类型的变量作为形参,构造交换函数;
(2)使用指针变量作为形参,在函数体中交换指针的指向;
(3)使用指针变量作为形参,在函数体中交换指针变量所指内存中存储的数据;
(4)使用随机数生成器确定交换发生的次数,选择每轮要执行的交换方法;
(5)使用while循环语句控制交换进行的轮数;
(6)使用switcj语句产生的随机数选择本文轮执行的交换方法。
代码实现:
#include <stdio.h>
#include <stdlib.h>
//函数声明
void exc1(int l, int r);
void exc2(int* l, int* r);
void exc3(int* l, int* r);
//游戏模拟
//使用随机函数获取交换的次数,和每次交换所选择的函数
int main()
{
int a = 0, i = 0, j;
int l = 1, r = 0;
srand((unsigned int)time(0));
i = 5 + (int)(rand() % 5);
j = i;
printf("a:%d,i:%d\\n",a,i);
printf("原始状态:\\n");
printf("l=%d,r=%d\\n\\n", l, r);
while (i>0)
{
i--;
a = 1 + (int)(rand() % 3);
switch (a)
{
case 1:
exc1(l, r);
printf("exc1-第%d次交换后的状态\\n", j - i);
printf("l=%d,r=%d\\n\\n", l, r);
break;
case 2:
exc2(&l, &r);
printf("exc2-第%d次交换后的状态\\n", j - i);
printf("l=%d,r=%d\\n\\n", l, r);
break;
case 3:
exc3(&l, &r);
printf("exc3-第%d次交换后的状态\\n", j - i);
printf("l=%d,r=%d\\n\\n", l, r);
break;
default:
break;
}
}
return 0;
}
//函数定义
void exc1(int l, int r)
{
int tmp;
tmp = l; //交换形参的值
l = r;
r = tmp;
}
void exc2(int* l, int* r)
{
int* tmp;
tmp = l; //交换形参的值
l = r;
r = tmp;
}
void exc3(int* l, int* r)
{
int tmp;
tmp = *l; //交换形参变量指向内容的值;
*l = *r;
*r = tmp;
}
运行截图:
三、奇数阶幻方
描述:将从1至n平方的自然数排列成纵横各有n个数的矩阵,使每行每列每条主对角线上的n个数之和都相等。
分析:
(1)矩阵的行数、列数、矩阵中的元素的数量都由n确定,在程序中设置scanf()函数,由用户手动控制魔方的规模。(案例只针对奇数阶的幻方,所以如果输入的数据不是奇数,再使用goto语句回到输入函数之前
(2)元素的数量不确定,所以使用malloc()函数动态申请存储空间;
(3)数据按列优先存储在malloc函数开辟的空间中,在输出时,每输出n个数据进行一次换行;
(4)将所有的操作封装在一个函数中,在主函数中调用该函数,幻方输出之后,使用free()函数释放函数中申请的堆空间。
代码实现:
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
void array();
int main ()
{
array(); //调用array函数
return 0;
}
void array()
{
int n, i, j, idx, num, MAX;
int* M; //定义一个一维数组指针,按行优先存储矩阵中的元素
printf("请输入n:");
input:
scanf("%d", &n);
if (n % 2 == 0) //n是偶数,则重新输入
{
printf("n不为奇数,请重新输入:");
goto input;
}
MAX = n*n; //MAX为幻方中的最大值,也是元素个数
M = (int*)malloc(sizeof(int)*MAX); //分配存储空间
M[n / 2] = 1; //获取数值1的列标
i = 0;
j = n / 2;
//从2开始确定每个数的存放位置
for (num = 2; num <= MAX; num++)
{
i = i - 1;
j = j + 1;
if ((num - 1) % n == 0) //当前数是n的倍数
{
i = i + 2;
j = j - 1;
}
if (i < 0) //当前数在第0行
i = n - 1;
if (j>n - 1) //当前数在最后一列,即n-1列
j = 0;
idx = i*n + j; //根据二维数组下标与元素的对应关系
//找到当前数在数组中的存放位置
M[idx] = num;
}
//打印生成的幻方
printf("生成的%d阶幻方:", n);
idx = 0;
for (i = 0; i < n; i++)
{
printf("\\n"); //每n个数据为一行
for (j = 0; j < n; j++)
{
printf("%3d", M[idx]);
idx++;
}
}
printf("\\n");
free(M); //手动释放堆空间
}
运行截图:
四、快速排序
#include <stdio.h>
//快速排序
void QuickSort(int *arr, int left, int right)
{
//如果数组左边的索引大于或等于右边索引,说明该序列整理完毕
if (left >= right)
return;
int i = left;
int j = right;
int key = *(arr + i); //使用key来保存作为键值的数据
//本轮排序开始,当i=j时本轮排序结束,将值赋给arr[i]
while (i < j)
{
while ((i < j) && (key <= arr[j]))
j--; //不符合条件,继续向前寻找
*(arr + i) = *(arr + j);
//从前往后找一个大于当前键值的数据
while ((i < j) && (key >= arr[i]))
i++; //不符合条件,继续向后寻找
//直到i<j不成立时while循环结束,进行赋值
*(arr + j) = *(arr + i);
}
*(arr + i) = key;
QuickSort(arr, left, i - 1);
QuickSort(arr, i + 1, right);
}
//输出数组
void print(int *arr, int n)
{
for (int i = 0; i < n; i++)
printf("%d ", *(arr + i));
}
int main()
{
int arr[10] = { 3, 5, 6, 7, 2, 8, 9, 1, 0, 4 };
printf("原数组:\\n");
print(arr, 10);
QuickSort(arr, 0, 9); //排序算法
printf("\\n排序后的数组:\\n");
print(arr, 10); //输出数组
return 0;
}
运行截图:
五、天生棋局
描述:创建棋盘、初始化棋盘、输出棋盘、销毁棋盘。
代码实现:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
int ** createBoard(int n)//用返回类型是二维指针的类型,创建一个棋盘,长度由主函数传递来
{
int **p = (int**)calloc(sizeof(int*), n);
int i = 0;
for (i = 0; i < n; i++)
{
p[i] = calloc(sizeof(int), n);
}
return p;
}
//初始化棋盘
int initBoard(int **p, int n, int tmp)//用随机数下棋
{
int i, j;
int t = tmp;
while (t > 0)
{
i = rand() % n;
j = rand() % n;
if (p[i][j] == 1)//坐标内已有棋子则再次循环
continue;
else
{
p[i][j] = 1;
t--;
}
}
return 0;
}
//输出棋盘
int printfBoard(int **p, int n)
{
int i, j;
for (i = 0; i < n; i++)//用行列计数变量检测同一行或列是否多于2个棋子
{
for (j = 0; j < n; j++)
{
if (p[i][j] == 1) //输出棋子
{
printf("●");
}
else //搭建棋盘
{
if (i == 0 && j == 0)
printf("┏");
else if (i == 0 && j == n - 1)
printf("┓");
else if (i == n - 1 && j == 0)
printf("┗");
else if (i == n - 1 && j == n - 1)
printf("┛");
else if (j == 0)
printf("┠");
else if (i == n - 1)
printf("┷");
else if (j == n - 1)
printf("┨");
else if (i == 0)
printf("┯");
else
printf("┼");
}
}
putchar('\\n');
}
for (i = 0; i < n; i++)//用行列两个循环判断是否行列上有两个相邻的棋子
{
for (j = 0; j<n; j++)
{
if (p[i][j] == 1)
{
if (j>0 && p[i][j - 1] == 1) //判断同一行有无相邻棋子
{
printf("好棋!\\n");
return 0;
}
if (i > 0 && p[i - 1][j] == 1) //判断同一列有无相邻棋子
{
printf("好棋\\n");
return 0;
}
}
}
}
printf("不是好棋\\n");
return 0;
}
//销毁棋盘
void freeBoard(int **p, int n)
{
int i;
打卡 c语言趣味编程 求勾股数