C语言学习 第6天 【学会C语言就靠它了......】

二、随机函数

随机函数能够产生随机的整数。

计算机的随机都是假随机。是使用一套算法计算出来的一系列让人看不出规律的数。

#include <stdlib.h> 
std stdandard标准    lib   library库    标准库头文件,头文件中声明了很多不同功能函数。

#include <time.h> 
srand();  //设置随机种子的函数,后面生成的一系列随机数,都是根据种子数计算出来的。
//seed random		set random

rand();  //random  产生一个随机数,每调用一次rand()会产生一个随机数

time(); //获得当前时间,单位是秒

示例:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int i;
    srand(0);//使用0作为随机的种子数,后面生成的所有的随机数都是根据0计算出来的
	for(i = 0;i < 10;i++)//循环10次生成10个随机数
	{
		printf("%d ", rand());//rand()通过返回值给我们提供随机数
	}
	printf("\n");
	return 0;
}

所有人得到的随机数都是一样的,证明计算机的随机数是假随机,是根据种子数使用一套算法计算出来的。

所以我们只需要让种子不一样,得到的随机数也就不一样

示例:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
	srand(time(0));//为了让随机看上去更加的真实,我们使用当前的时间作为种子数,time(0)是固定用法获得当前时间的功函数,时间从1970年..到现在的秒数,只要程序不是在同一秒内运行,那么生成的随机数就不一样
	int i;
	for(i = 0;i < 10;i++)
	{
		int r = rand()%100;//rand生成的随机数,是无符号int全范围的数,范围太大,所以我们会使用%限制范围,%100将随机数范围限制在0~99
		printf("%d ", r);
	}
	printf("\n");
	return 0;
}

思考:

-10~10闭区间

N表示随机数范围内数的数量 -10~10闭区间之间有21个数

rand()%N+范围内最小值

rand()%21+(-10)

随机数编程示例:

随机出一个数,一个 0~10 以内的数字。然后请你猜 3 次。

如果猜对了,结束程序,并且输出"Congratulations!"。

如果没有猜对,那么提示一下,你的输入是偏大了,还是偏小。如果3次没猜对,GAMEOVER

1.随机一个数,作为答案

2.循环3次,for

3.用户输入

4.比较大小(输入和答案比)

5.如果猜对,输出"Congratulations!",结束循环

6.如果猜错,输出大或者小,回到步骤3

7.循环结束i==3说明3次都猜错了。输出GAMEOVER

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
	int i, num, result;
	srand(time(0));
	result = rand()%10;
	//printf("result = %d\n", result);
	for(i = 0;i < 3;i++)
	{
		scanf("%d", &num);
		if(num > result)
		{
			printf("偏大了\n");
		}
		else if(num < result)
		{
			printf("偏小了\n");
		}
		else
		{
			printf("恭喜猜对了%d\n",result);
			break;
		}
	}
	if(i == 3)//说明没有执行猜对了,因为猜对了结束循环,此时i一定小于3
	{
		printf("GAME OVER %d\n", result);
	}
	return 0;
}

阶段练习:

编写程序,实现:彩票35选7.
要求:

  1. 用户输入7个数(模拟买彩票选数),保证不能有重复。
  2. 系统随机出 1~35 之间不重复的7个数。
  3. 开奖时,统计猜中数值的个数。(不按顺序)
  4. 打印中奖金额。

思路:

用户输入的数组 int user[7]

系统开奖的数组 int sys[7]

查重思路

int a[5] = {1,2,3,4,5};
int b[5] = {2,3,4,5,6};
int i, j;
//使用a中的每个元素,和b中的所有元素进行比较
for(i = 0;i < 5;i++)//遍历a
{
//当i=0时,a[0]会和b数组所有元素比较一遍
//当i=1时,a[1]会和b数组所有元素比较一遍
	for(j = 0;j < 5;j++)//遍历b
	{
		if(a[i] == b[j])//这个if一共会比较多少次?25次
		{
			
		}
	}
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
	srand(time(0));
	int user[7];
	int sys[7];
	//用户输入
	int i, j;
	for(i = 0;i < 7;i++)
	{
		scanf("%d", &user[i]);
		//判断输入在1~35之间
		if(user[i]<1 || user[i]>35)
		{
			i--;//i元素重新输入
			printf("输入超出范围1~35\n");
			continue;
		}
		//查重
		//判断i元素之前是否有重复
		for(j = 0;j < i;j++)
		{
			if(user[i] == user[j])//判断重复
			{
				i--;//i元素重新输入
				printf("出现输入的重复\n");
				break;
			}
		}
	}
	//生成开奖数字
	for(i = 0;i < 7;i++)
	{
		sys[i] = rand()%35+1;//1~35
		//查重 判断i元素之前是否有重复
		for(j = 0;j < i;j++)
		{
			if(sys[i] == sys[j])
			{
				i--;
				break;//停止for(j = 0;j < i;j++)
			}
		}
	}
	
	//输出开奖数字
	for(i = 0;i < 7;i++)
	{
		printf("%d ", sys[i]);
	}
	printf("\n");
	
	//判断中奖信息
	int count = 0;//计数,初始化为0
	for(i = 0;i < 7;i++)//sys
	{
		for(j = 0;j < 7;j++)//user
		{
			if(sys[i] == user[j])
			{
				count++;
			}
		}
	}
	//显示中奖信息
	switch(count)
	{
	case 7:
		printf("1000000\n");
		break;
	case 6:
		printf("100000\n");
		break;
	case 5:
		printf("10000\n");
		break;
	case 4:
		printf("1000\n");
		break;
	case 3:
		printf("10\n");
		break;
	case 2:
	case 1:
	case 0:
		printf("tk\n");
	}

	return 0;
}

三、冒泡排序

为了方便数据处理,我们经常需要排序。

排序的方法不止冒泡排序。为什么学习冒泡?因为它好写。

冒泡排序是排序效率最低的排序方法之一。

当排序的数据量很小的时候,是很难感觉到高效的排序算法的效率提升的。但是高效的排序算法代码一般都挺难写,所以当数据量很小的时候,冒泡排序好写的优势就体现出来了。

1.冒泡的原理

分析: int a[7] = {85, 72, 65 ,79, 53, 95, 87};

冒泡的原理(升序):比较数组中相邻的两个元素,前者大于后者,交换两个元素的值。

有N个数,需要比较N-1次。
在这里插入图片描述

2.冒一个泡

#include <stdio.h> 

int main()
{	
	int a[] = {85, 72, 65, 79, 53, 95, 87};
	int i;
	//循环遍历整个数组,因为数组有7个数,所以我们需要比较7-1次
	for(i = 0;i < 7-1;i++)
	{
		if(a[i] > a[i+1])//比较相邻两个元素
		{
            //前者大于后者,就交换两个元素的值
			int temp = a[i];
			a[i] = a[i+1];
			a[i+1] = temp;
		}
	}
    //此时完成冒泡,输出查看结果
	for(i = 0;i < 7;i++)
	{	
		printf("%d ", a[i]);//72 65 79 53 85 87 95
	}
	printf("\n");
	return 0;
} 

3.冒泡排序

我们只需要反复的执行冒泡过程,最终数组就会有序。需要进行的冒泡次数是N-1次,7个数需要冒泡6次。

在这里插入图片描述

#include <stdio.h> 

int main()
{	
	int a[] = {85, 72, 65, 79, 53, 95, 87};
	int i,j;
    //反复进行冒泡,需要进行N-1次冒泡,数组有序
	for(j = 0;j < 7-1;j++)
	{
        //内层循环用来冒一个泡,-j的目的是因为每一轮冒泡都比上一轮少比较一次
		for(i = 0;i < 7-1-j;i++)
		{
			if(a[i] > a[i+1])
			{
				int temp = a[i];
				a[i] = a[i+1];
				a[i+1] = temp;
			}
		}
	}
    //输出结果
	for(i = 0;i < 7;i++)
	{	
		printf("%d ", a[i]);
	}
	printf("\n");
	return 0;
}

思考:

如果在某一轮冒泡的时候,没有发生交换,说明数组已经有序了,那么后面的冒泡轮次就没有比较进行了。

比如上图中是在第4轮冒泡中完成的数组排序,然后我们在第5轮冒泡的时候发现没有发生交换,于是第5轮之后的冒泡轮次就没有必要执行了。

#include <stdio.h> 

int main()
{	
	int a[] = {85, 72, 65, 79, 53, 95, 87};
	int i,j;
    //反复进行冒泡,需要进行N-1次冒泡,数组有序
	for(j = 0;j < 7-1;j++)
	{
        int flag = 0;//用作标记本轮冒泡中是否发生交换
        //内层循环用来冒一个泡,-j的目的是因为每一轮冒泡都比上一轮少比较一次
		for(i = 0;i < 7-1-j;i++)
		{
			if(a[i] > a[i+1])
			{
				int temp = a[i];
				a[i] = a[i+1];
				a[i+1] = temp;
                flag = 1;//如果发生交换,改变flag的值
			}
		}
        if(flag == 0)
        {
            break;//如果flag值没有发生改变,那么说明数组已经有序,结束冒泡轮次
        }
	}
    //输出结果
	for(i = 0;i < 7;i++)
	{	
		printf("%d ", a[i]);
	}
	printf("\n");
	return 0;
}

四、二维数组

1. 二维数组的本质

在这里插入图片描述

2. 如何定义

int a[2][3];

[2]说明a是有2个元素组成的数组。
[3]说明a的每个元素,是一个3个元素组成的一维数组。
int 说明作为a的子数组元素类型是int。
这样的数组a我们简称为二维数组。
换句话说,数组元素是一维数组的数组,我们叫做二维数组。

为了方便表达叫作为a元素的数组为 子数组。注意,C语言中没有子数组的概念

3.如何赋值

a[0][0] = 10;//a[0]数组的0元素赋值  10   是int变量
a[1][2] = 20;//a[1]数组的2元素赋值  20	  是int变量

能不能给 a[0]赋值?不能,数组不能被整体赋值,只能对元素赋值,如果元素还是数组,那么就得对元素的元素赋值。

4. 遍历

遍历二维数组就是在遍历N个一维数组

遍历二维数组,一般使用双重for循环,外层循环遍历第一个角标,内层循环遍历第二个角标。

#include <stdio.h>

int main()
{
    int a[2][3];
    int i, j;
    for(i = 0;i < 2;i++)//遍历数组a,数组a有2个元素 分别是a[0]和a[1]
    {
        //遍历子数组
        /*
        i = 0时,遍历a[0]数组  a[0]数组有3个元素
        i = 1使,遍历a[1]数组  a[1]数组有3个元素
        */
        for(j = 0;j < 3;j++)
        {
            a[i][j] = i*j;//a[i][j]是一个整型变量
            printf("%d\n", a[i][j]);
        }
    }
    return 0;
}

5. 初始化

三种初始化的概念和一维数组是一样的。

完全初始化:

int a[2][3] = {{1,2,3},{4,5,6}};
//a[0]:1,2,3   a[1]:4,5,6
int a[2][3] = {1,2,3,4,5,6};
//a[0]:1,2,3   a[1]:4,5,6
//在完全初始化中,里面的{}写不写无所谓

部分初始化:

int a[2][3] = {1,2,3}; 
//a[0]:1,2,3  a[1]:0 0 0  a[1]默认补0
int a[2][3] = {{1},{2,3}};
//a[0]:1,0,0  a[1]:2,3,0

默认初始化:

在二维数组中,第一个角标表示数组的元素个数,所以默认初始化的时候,只有第一个角标可以省略。

第二个角标表示数组的元素类型,所以第二个角标一定不能省略。

int a[][3] = {{1,2,3},{4,5,6}};
//a[0]:1,2,3  a[1]:4,5,6
int a[][3] = {1,2,3,4};
//a[0]:1,2,3  a[1]:4,0,0

6. 类型

二维数组的类型是二维数组的子数组的元素类型,可以是任何类型。

五、二维数组编程示例

编程示例1:

定义一个二维数组。初始化。并输出

#include <stdio.h>

int main()
{
	int a[3][5] = {{1,2,3,4,5},{5,4,3,2,1},{1,3,5,7,9}};
	int i, j;
	for(i = 0;i < 3;i++)
	{
		for(j = 0;j < 5;j++)
		{
			printf("%d ", a[i][j]);//打印a[i]数组的j元素
		}
		printf("\n");//每打印完一个数组换行
	}
	return 0;
}

编程示例2:

对二维数组中每个元素相加,求和

先初始化一个二维数组。使用示例1数组。

#include <stdio.h>

int main()
{
	int a[3][5] = {{1,2,3,4,5},{5,4,3,2,1},{1,3,5,7,9}};
	int i, j;
	int sum = 0;
	for(i = 0;i < 3;i++)
	{
		for(j = 0;j < 5;j++)
		{
			sum += a[i][j];
		}
	}
	printf("%d\n", sum);
	return 0;
}

编程示例3:

已知,有两个二维数组,初始化的。请将这个两个二维数组中对应位置的元素相加,将结果放在第三个二维数组中

#include <stdio.h>

int main()
{
	int a[2][3] = {1,2,3,4,5,6};
	int b[2][3] = {3,4,5,6,7,8};
	int c[2][3];
	int i, j;
	for(i = 0;i < 2;i++)
	{
		for(j = 0;j < 3;j++)
		{
			c[i][j] = a[i][j]+b[i][j];
			printf("%d ", c[i][j]);
		}
		printf("\n");
	}
	return 0;
}

编程示例4:

用二维数组表示一个6*8的平面直角坐标系,默认显示*,输入对应的位置和一个字符,给二维数组中相应的位置赋值,以行列的形式打印二维数组。

这道题的根本目的是使用二维数组表示直角坐标系中显示的数据。是二维数组的常见用法之一。

  1. 第一个角标表示Y轴,第二个角标表示X轴。
  2. X轴向右递增,Y轴向下递增。
  3. 坐标原点(0,0)在左上角。

2 3 &

char a[8][6];

* * * * * *			a[0]
* * * * * *			a[1]
* * * * * *			a[2]
* * & * * *			a[3]
* * * * * *			a[4]
* * * * * *			a[5]
* * * * * *			a[6]
* * * * * *			a[7]
#include <stdio.h>

int main()
{
    char a[8][6];
    printf("初始化坐标系:\n");
    for (int i = 0; i < 8; ++i) {
        for (int j = 0; j < 6; ++j) {
            a[i][j]='*';
            printf("%c ",a[i][j]);
        }
        printf("\n");
    }
    int x,y;
    char signal;
    printf("请输入坐标和符号 :\n");
    scanf("%d %d %c",&x,&y,&signal);
    a[y][x]=signal;
    printf("输入的符号在坐标轴中的位置为:\n");
    for (int i = 0; i < 8; ++i) {
        for (int j = 0; j < 6; ++j) {
            printf("%c ",a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

编程示例5:

鞍点。 判断数组中是否存在鞍点,在该行最大,并且在该列最小

int a[3][4];

1 2 6 4 a[0]

5 6 7 8 a[1]

9 10 11 12 a[2]

6是鞍点

#include <stdio.h>

int main()
{
    int a[3][4]={1,2,6,4,
                 5,6,7,8,
                 9,10,11,12};
    int i,j,k,x,y;
    printf("二维数组为:\n");
    for ( i = 0; i < 3; ++i) {
        for ( j = 0; j < 4; ++j) {
            printf("%d ",a[i][j]);
        }
        printf("\n");
    }
    int max=a[0][0];
    for ( i = 0; i < 3; ++i) {
        for ( j = 0; j < 4; ++j) {
            if (a[i][j] > max)
            {
                x=j;
                y=i;
                max=a[i][j];
            }
        }
        int count=0;
        for ( k = 0; k < 3; ++k) {
            if(a[k][x]<max)
            {
                count++;
            }
        }
        if(count==0)
        {
            printf("数组的鞍点为%d,坐标为(%d,%d)\n",
                   max,y,x);
            break;
        }
    }
    return 0;
}

编程示例6:

请将杨辉三角形(7阶)保存在二维数组中,并输出。

1 0 0 0 0

1 1 0 11=00+01

1 2 1 0 21=10+11

1 3 3 1 32=21+22

1 4 6 4 1

1 5 10 10 5 1

#include <stdio.h>
#define YH 7

int main()
{
    int yh[YH][YH]={1};
    for (int i = 1; i < YH ; ++i) {
        yh[i][0]=1;
        for (int j = 1; j < i+1; ++j) {
            yh[i][j]=yh[i-1][j-1]+yh[i-1][j];
        }
    }
    for (int i = 0; i < YH ; ++i) {
        for (int j = 0; j < YH - i; ++j) {
            printf("  ");
        }
        for (int j = 0; j < i+1; ++j) {
            printf("%4d ",yh[i][j]);
        }
        printf("\n");
    }
    return 0;
}

编程示例6:

请将杨辉三角形(7阶)保存在二维数组中,并输出。

1 0 0 0 0

1 1 0 11=00+01

1 2 1 0 21=10+11

1 3 3 1 32=21+22

1 4 6 4 1

1 5 10 10 5 1

#include <stdio.h>
#define YH 7

int main()
{
    int yh[YH][YH]={1};
    for (int i = 1; i < YH ; ++i) {
        yh[i][0]=1;
        for (int j = 1; j < i+1; ++j) {
            yh[i][j]=yh[i-1][j-1]+yh[i-1][j];
        }
    }
    for (int i = 0; i < YH ; ++i) {
        for (int j = 0; j < YH - i; ++j) {
            printf("  ");
        }
        for (int j = 0; j < i+1; ++j) {
            printf("%4d ",yh[i][j]);
        }
        printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super Mark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值