复习:
字符串常量
“” 以’\0’ ascii 0
字符常量初始化字符数组
可以用字符数组存放字符串
字符输入输出函数
char c;
c = getchar();//获得一个字符
putchar(c);
字符串输入输出函数
char buf[100];
gets(buf);//获得输入的字符串 能得到空格
scanf("%s", buf);//得不到空格
puts(buf);//输出字符串,会自动换行
printf("%s\n", buf);
字符串操作4个函数
#include <string.h>
strlen();//获得字符串的长度 字符串中除了'\0'以外所有字符的数量
//返回值:字符串的长度
//参数:可以是字符串常量,也可以是存放字符串的数组名
strcpy();//将一个字符串拷贝到一个字符类型数组中
//返回值:参数1
//参数1:被赋值的数组名
//参数2:要复制的字符串常量,或者存放字符串的数组名
strcat();//拼接字符串,将一个字符串追加到另一个字符串的尾部
//返回值:参数1
//参数1:存放被追加的字符串的数组名
//参数2:要追加的字符串常量,或者存放字符串的数组名
strcmp();//比较两个字符串 比较的是第一个不相等的字符的ascii码值
//参数1:第一个字符串常量,或者存放字符串的数组名
//参数2:第二个字符串常量,或者存放字符串的数组名
//返回值; 1 s1>s2 0 s1==s2 -1 s1<s2
随机函数
#include <stdlib.h>
srand(time(0));//初始化随机数种子 每次运行程序,种子应该是不一样的,所以我们使用时间作为种子 只调用一次
rand();//获得一个随机数,但是这个数字可能很大。
rand()%数的范围+最小值
作业
将两个数组中的字符串连接起来。 printf("%s",a); 输出“hello world”
char a[20] = "hello ";
char b[20] = "world ";
#include <stdio.h>
int main()
{
char a[20] = "hello ";
char b[20] = "world";
int i = 0;
//找到a中\0的位置
while(a[i] != '\0')
{
i++;
}
int j = 0;
//将b中的字符一个一个的赋值给a
while(b[j] != '\0')
{
a[i++] = b[j++];
}
//补\0
a[i] = '\0';
printf("%s\n", a);
return 0;
}
作业(选做,会讲)
统计一个字符串中有多少个单词? 最大的单词长度是多少?(问题2:选做)
char s[] = “Struggle for a better future”;
- 如果字符串只有一个单词,且没有用空格
#include <stdio.h>
int main()
{
char s[100] = " apple banana hello ";
int i = 0;
int count = 0;
int maxLen = 0;
while(s[i] != '\0')
{
int len = 0;//循环体每执行一次,是找一个单词的长度
//过滤空格
while(s[i] == ' ')
{
i++;
}
while(s[i]!='\0' && s[i]!=' ')
{
len++;
i++;
}
if(len != 0)
{
count++;
if(maxLen < len)
{
maxLen = len;
}
}
}
printf("count = %d maxLen = %d\n", count, maxLen);
return 0;
}
作业(选做,会讲)
彩票的故事: 35 选 7 1 ~ 35
-
1 ~ 35 之间的七个数随机出来(彩票站)
-
1 ~ 35 之间的七个数自选 (用户)不允许重复
-
比较中奖的个数(对应上几个数字)
-
兑奖
#include <stdio.h>
#include <stdlib.h>
int main()
{
srand(time(0));
int results[7] = {0};
int i;
//1 生成7个随机数
for(i = 0;i < 7;i++)
{
results[i] = rand()%35+1;//随机一个数
int j;
//判断当前数组中有没有这个数
//2 判断是否有重复
for(j = 0;j < i;j++)
{
if(results[j] == results[i])
{
i--;//让外层循环的下一次循环i的值不变
break;//已经找到一个相同的数,后面没必要再判断
}
}
}
printf("input not 重复\n");
int userNums[7] = {0};
//3 用户输入
for(i = 0;i < 7;i++)
{
scanf("%d", &userNums[i]);
if(userNums[i]<1 || userNums[i]>35)
{
i--;
printf("超出了1~35的范围\n");
continue;
}
//4 判断输入重复
int j;
for(j = 0;j < i;j++)
{
if(userNums[j] == userNums[i])
{
i--;
printf("输入重复了,重新输入\n");
break;
}
}
}
int count = 0;
//5 比较两个数组中的重复个数
for(i = 0;i < 7;i++)//results
{
int j;
for(j = 0;j < 7;j++)//userNums
{
if(results[i] == userNums[j])
{
count++;
break;
}
}
}
//6 输出结果
switch(count)
{
case 7:
printf("1000 0000\n");
break;
case 6:
printf("10000\n");
break;
case 5:
printf("100\n");
break;
case 4:
printf("2\n");
break;
default:
printf("谢谢参与\n");
}
//7 输出两个数组
for(i = 0;i < 7;i++)
{
printf("%d %d\n", results[i], userNums[i]);
}
return 0;
}
1、冒泡排序
为了方便处理数据,我们会把无序的数据编程有序的。
冒泡排序是最好写的排序算法,也是最慢的排序算法。
当数据量不大的时候,冒泡排序不会有多么慢,此时好写的优势就体现出来了。
原理
分析: int a[7] = {85, 72, 65 ,79, 53, 95, 87};
原理(升序):每次两个数进行比较,从数组的前两个元素开始,如果前面的数 > 后面的数,就交换
第一趟会求出一个最大值,并且放在最后面,
然后 依此类推,经过最多 N-1 趟,排好序
72, 65, 79, 53, 85, 87, [95] ----> 第一轮,95在最后面
65, 72, 53, 79, 85, [87],95 ----> 第二轮,87 求出,最大
65, 53, 72, 79, [85],87,95 ----> 第二轮,85 求出,最大
53, 65, 72, [79],85,87,95
53, 65, [72],79,85,87,95
53, [65] ,72,79,85,87,95
7个数,比较6轮,每轮,比较这些次(6, 5, 4 ,3, 2, 1)
冒一个泡
#include <stdio.h>
int main()
{
int a[] = {85, 72, 65, 79, 53, 95, 87};
int i;
for(i = 0;i < 7-1;i++)//比较的次数,是数组的长度-1
{
//因为升序排,所以a[i]>a[i+1]交换
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;
}
冒泡排序
#include <stdio.h>
int main()
{
int a[] = {85, 72, 65, 79, 53, 95, 87};
int i,j;
for(j = 0;j < 7-1;j++)
{
//-j的目的,是每次冒泡都比上一次少比较一个数
for(i = 0;i < 7-1-j;i++)//比较的次数,是数组的长度-1
{
//因为升序排,所以a[i]>a[i+1]交换
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;
}
排序过程
j = 0
j=1
j=2
j=3
j=4
j=5
2、二维数组
1. 二维数组的本质
在C语言中只有一维数组,二维数组的本质还是一维数组。
所谓的二维数组只是一个简称,是数组元素是一维数组的一维数组。
a[0] 是一个一维数组,3个元素,每个元素是int类型
a[1] 是一个一维数组,3个元素,每个元素是int类型
a[0][0] ~a[1][2] 都是int类型
a[0][0]是a[0]数组的0元素
2. 如何定义
int a[2][3];
2 是一维数组a的元素个数
3 是作为一维数组a的元素的数组的元素个数
int 是作为一维数组a的元素的数组的元素类型
3.如何赋值
a[0][0] = 10;
a[1][2] = 20;
4. 遍历
因为二维数组的元素有两个角标,所以我们一般使用循环嵌套遍历二维数组。
int a[2][3];
int i, j;
for(i = 0;i < 2;i++)//外层循环一般遍历第一个角标
{
for(j = 0;j < 3;j++)//内层循环一般遍历第二个角标
{
a[i][j] = i*j;//遍历赋值
}
}
5. 初始化
完全初始化:
int a[2][3] = {{1,2,3},{4,5,6}};
int a[2][3] = {1,2,3,4,5,6};
部分初始化:
int a[2][3] = {1,2,3}; //a[0][0]=1 a[0][1]=2 a[0][2]=3 a[1][0]~a[1][2]=0
int a[2][3] = {{1},{2,3}};//a[0][0]=1 a[0][1]=0 a[0][2]=0 a[1][0]=2 a[1][1]=3 a[1][2]=0
默认初始化:
第一个角标才是数组a的长度,才可以省略,第二个角标是元素数组的长度,所以不可以省略。
int a[][3] = {{1,2,3},{4,5,6}};//数组a的长度是2
int a[][3] = {1,2,3,4};//a[0][0]=1 a[0][1]=2 a[0][2]=3 a[1][0]=4 a[1][1]=0 a[1][2]=0
6. 类型
是作为数组元素的一维数组的元素类型
int a[2][3]在逻辑上可以被int a[6]代替的,使用二维数组的好处是可以将数据分类。
例题1:
定义一个二维数组。赋值。并输出
#include <stdio.h>
int main()
{
int a[2][3];
int i, j;
for(i = 0;i < 2;i++)
{
for(j = 0;j < 3;j++)
{
a[i][j] = i*j;
}
}
for(i = 0;i < 2;i++)
{
for(j = 0;j < 3;j++)
{
printf("a[%d][%d] = %d\n", i,j,a[i][j]);
}
}
return 0;
}
练习1:
对二维数组中每个元素相加,求和
先初始化一个二维数组。
#include <stdio.h>
int main()
{
int a[2][3] = {23,45,67,89,34,67};
int i, j;
int sum = 0;
for(i = 0;i < 2;i++)
{
for(j = 0;j < 3;j++)
{
sum += a[i][j];
}
}
printf("sum = %d\n", sum);
return 0;
}
练习2:
已知,有两个二维数组。请将这个两个二维数组中对应位置的元素相加,将结果放在第三个二维数组中
#include <stdio.h>
int main()
{
int a[2][3] = {23,45,67,89,34,67};
int b[2][3] = {76,65,54,34,67,9};
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("c[%d][%d] = %d ", i, j, c[i][j]);
}
printf("\n");
}
return 0;
}
练习3:
找到二维数组中的最大值,以及最大值的角标。
#include <stdio.h>
int main()
{
int a[3][4] ={12,34,45,56,67,89,90,7,5,32,45,7};
int i, j;
int max = a[0][0];
int maxI = 0, maxJ = 0;
for(i = 0;i < 3;i++)
{
for(j = 0;j < 4;j++)
{
if(a[i][j] > max)
{
max = a[i][j];
maxI = i;
maxJ = j;
}
}
}
printf("max = %d i = %d j = %d\n", max, maxI, maxJ);
return 0;
}
练习4:
找到二维数组中,每个元素数组的最小值,并且求和
#include <stdio.h>
int main()
{
int a[3][4] = {12,34,45,56,67,89,90,17,5,32,45,7};
int i;
int sum = 0;
for(i = 0;i < 3;i++)
{
int min = a[i][0];//每个小数组都应该取第一个数和该数组后面的数比较
int j;
for(j = 1;j < 4;j++)
{
if(a[i][j] < min)
{
min = a[i][j];
}
}
sum += min;
}
printf("sum = %d\n", sum);
return 0;
}
作业:
请将杨辉三角形(7阶)保存在二维数组中,并输出。
1 0
1 1 0
1 2 1 0
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
a[i][j] = a[i-1][j]+a[i-1][j-1]
作业1:
鞍点。 判断数组中是否存在鞍点,在该行最大,并且在该列最小
1 2 6 4
5 6 7 8
9 10 11 12
6是鞍点
作业2:(和二维数组没有关系)
输入一个字符串,转换为数字 例如:“1234” --> int 1234
sum=sum*10+a; a是将数字字符转换成的整数
作业3:
尝试输出如下图形。 输入位子信息和字符信息,可以任选位置,并将该位置的字符换成输入的新字符。
二维数组常用来表示一个平面直角坐标系。
一般没规定坐标原点在左上角;
X轴向右递增
y轴向下递增
第一个角标表示y轴
第二个角标表示x轴
2 3 &
* * * * *
* ^ * * *
* * * * *
* * & * *
* * * * *