目录
一、二维数组
二维数组:以一维数组为元素的数组。我们知道一维数组是同一类型元素的集合
1. 二维数组初始化
与一维数组类似,我们可进行类比推理
1.1 完全初始化
1.2 部分初始化
1.3 默认初始化
2.遍历二维数组
可使用循环嵌套的思想:外循环控制行数,里循环控制列数 。应用:冒泡排序
练习:输入一个数,查询该数在二维数组当中是否存在该数,如果存在计算有多少个这样的数
int a[3][4] = {{1,2,3,4}, {5,6,7,3}, {9,3,11,12}};
#include <stdio.h>
int main()
{
int a[3][4] = {{1,2,3,4}, {5,6,7,3}, {9,3,11,12}};
int i,j,num;
int count = 0;//用来统计num出现的次数
printf("Please input you find num:\n");
scanf("%d",&num);//由键盘输入,确定要查找的数
for(i = 0; i < 3; i++)
{
for(j = 0; j < 4; j++)
{
if(num == a[i][j])
{
count++;
}
}
}
if(count)//if(count != 0)
{
printf("%d存在,存在%d个!!\n",num,count);
}
else
{
printf("不存在!!\n");
}
return 0;
}
练习:求两个矩阵之和放在第三个矩阵中 (3行4列),第三个矩阵也是三行四列
练习: 输出杨辉三角形 输出10阶即可
3.随机数
上面的程序并不是真的随机数
练习:中国福利彩票35选7 随机生成1-35内不重复的7个数字 然后让用户选择自己的一组号码 中奖规则,猜中7个500万 6个100万 5个1万 4个5000 3个500 0,1,2个没中奖
#include <stdio.h>
#include <time.h>
int main()
{
//我们在调用随机数之前,需要初始化随机种子
long t = time(NULL);//调用一次time函数,就可以得到1970距今的秒数
srand(t);//初始化随机种子,每一次srand的参数t,是一个变化的值,距今的秒数,在增大
int num = rand() % 10 + 1;//num里保存的是随机生成的数
printf("num is %d\n",num);
int a,i;//a用来存储,输入的数
for(i = 0; i < 5; i++)
{
printf("请输入你要猜的数:\n");
scanf("%d",&a);
if(a == num)
{
printf("Yes!!\n");
break;//猜对了,就结束循环
}
else if(a > num)
{
printf("bigger!!\n");
}
else // a < num
{
printf("smaller!!\n");
}
}
return 0;
}
2.3 中国福利彩票35选7 随机生成1-35内不重复的7个数字 然后让用户选择自己的一组号码 中奖规则:猜中
//1. 生成7个中奖号码 int lotteryNum[7]//注意生成7个中奖号码,有可能重复, 中奖号检测去重
rand() //随机数
i = 0 [0] ---> 12
i = 1 [1] ---> 5 74 % 35 + 1 == 5
i = 2 [2] ---> 7
i = 2 [3] ---> 5 39 % 35 + 1 == 5
for(i = 0; i < 7; i++)
{
lotteryNum[i] = rand() % 35 + 1;
//生成完随机数之后,需要去做去重校验
//用当前的lotteryNum[i] 跟 0 - i-1 每一个作比较
}
//2. 输入7个数,买彩票 int myMum[7]
//3. 统计中奖个数
//4. 打印输出中奖信息
#include <stdio.h>
#include <time.h>
int main()
{
int i,j,lotteryNum[7];//用来保存随机生成的7个中奖号码
int myNum[7];//用来保存购买的中奖号码
int count = 0;//用来统计中奖个数
srand(time(NULL));//初始化随机种子
for(i = 0; i < 7; i++)//1.随机生成7个中奖号码
{
//假设 已经生成了3个不重复的数 12 4 23 ,
//生成第4个数,循环i = 3
lotteryNum[i] = rand() % 35 + 1;
//用当前生成的lotteryNum[3] 和 他前边已经生成的数,逐个比较
for(j = 0; j < i; j++)
{
if(lotteryNum[i] == lotteryNum[j])
{
i--;
printf("出现过重复的数!!\n");
break;
}
}
}
for(i = 0; i < 7; i++) //2.输入7个数,代表自己购买的中奖号码
{
printf("请输入购买的第%d个号码:\n",i+1);
scanf("%d",&myNum[i]);
}
for(i = 0; i < 7; i++) //3.统计中奖个数
{
for(j = 0; j < 7; j++)
{
if(lotteryNum[i] == myNum[j])
{
count++;
}
}
}
//4.根据中奖个数,打印中奖信息
switch(count)
{
case 7:
printf("500W!!\n");
break;
case 6:
printf("100W!!\n");
break;
case 5:
printf("1W!!\n");
break;
case 4:
printf("5000!!\n");
break;
case 3:
printf("500!!\n");
break;
default:
printf("重在参与!!\n");
}
//将中奖号码和手里的号码都打印输出
for(i = 0; i < 7; i++)
{
printf("%d ",lotteryNum[i]);
}
printf("\n");
for(i = 0; i < 7; i++)
{
printf("%d ",myNum[i]);
}
printf("\n");
printf("count is %d\n",count);
return 0;
}
练习:寻找鞍点( 该行最大,该列最小为鞍点)
#include <stdio.h>
int main()
{
int a[3][4] = {{123,94,-10,218},{73,9,10,-83},{45,16,44,-99}};
//标志位法
int flag = 1;
int i,j,k;
int max,min;//用来保存该行的最大值 和 该列的最小值
int line = 0;//用来记录组大值所在的列
for(i = 0; i < 3; i++)// i = 0 1
{
line = 0;
//先假设每一行的第0列,为最大值
max = a[i][0];
for(j = 1; j < 4; j++)
{
if(max < a[i][j])
{
max = a[i][j];//抢过来,把最大值
//同时要记录最大值所在的列
line = j;
}
}
//上面的for结束后,我们就已找到了第i行 最大值的所在的列,保存在line中
//我再遍历最大值所在的列,去找最小值
//先假设最大值所在列的第0行为最小值
min = a[0][line];
//遍历最大值所在的列,找最小值
for(k = 1; k < 3; k++)
{
if(min > a[k][line])
{
min = a[k][line];
}
}
//将第i行的最大值 与 最大值所在列的最小值做比较
if(max == min)
{
printf("%d是鞍点!!\n",max);
flag = 0;//flag如果被修改了,就证明存在鞍点
}
}
if(flag)//如果flag的值保持1不变,那么说明不存在鞍点
{
printf("没有鞍点!!\n");
}
return 0;
}
4.atoi函数
功能:把字符型'1','2','3' 转化为数字1,2,3
方法1:
方法2:
练习:判断一个字符串中是否存在某个子串
二、函数
函数(通常用来完成某一个特定的功能的一段代码,把这段代码放到一起,形成一个函数)
1. 函数命名规范
标识符命名规范:1、名字只能有字母 数字 下划线组成,不能以数字开头 2、不能与关键字同名 3、见名之意
2. 系统函数与自定义函数
系统函数(操作系统自带的 (标准IO与LinuxIO) 学会调用)
自定义函数(自己写的函数) 功能由我们的代码决定
3. 参数及返回值
4. 函数总结
(1)函数名, 要清晰表达出函数的含义。代码通常是多人合作,一定要让别人能看懂自己写的代码
(2)函数名不要简写(程序写出来尽量能让别人看懂) set_student_name()
(3)函数名两种不同风格写法
SetStudentName windows风格 (第一个单词) //大驼峰
set_student_name linux 风格 (单词中间加_)
setStudentName ios 风格 //小驼峰
(4)函数参数
get_max(int x, int y, int z); //尽量不要太多,不要多于5个,如果参数多,影响程序的可读性
函数调用时参数个数与定义时参数个数要一致,参数的类型按照顺序类型相匹配
get_max(30, 40, 50); //参数调用时参数个数要与定义的一致
如果函数没有参数
void print_star(void)//()内的void代表无参数的意思,可省略
(5)函数返回值可有可无,如果有返回值,那么函数里一定要有return;
//一个函数,利用return只能返回1个值 一个函数只能返回一个值
void print_star(); //void表示函数无返回值,函数中return 表示函数结束,如果返回值是void , return
函数只要执行到return , 函数就结束
return > break > continue
(6)函数功能尽量单一 高内聚 低耦合
(7)函数行数不要太多(尽量1页能显示下)
三、指针
内存单元地址(编号)称为指针,又称为指针变量,是c语言, c++, objective c 特有的, 指针用好了非常方便,如果用不好,也会造成不好的后果
1.定义及初始化
指针定义(用来保存一个地址的变量,叫指针变量)
2.指针与数组
数组的名字就是数组的首地址,而数组在内存当中是连续存储的,所以可通过地址访问数组里的元素
&a[i] === p+i a[i] === *(p+i)
练习:用指针,求学生成绩和,平均值并打印,学生成绩放到一个数组中
3.指针与函数
将数组传递给一个函数,如果将数组传递给函数,通常传递数组名, 函数用指针接收
练习:实现一个函数,使用指针打印数组中所有元素
练习: 编写一个函数,将数组中n个数按反顺序存放
4.指针运算
1、两指针之间的关系运算表示它们指向的地址位置之间的关系。指向地址大的指针大于指向地址小的指针。
2、具有不同数据类型的指针之间的关系运算没有意义,指向不同数据区域的数据的两指针之间,关系运算也没有意义。
3、指针与一般整数变量之间的关系运算没有意义。但可以和零进行等于或不等于的关系运算,判断指针是否为空
#include <stdio.h>
void reverse(int* p, int* q)
{
while(p < q)
{
int temp = *p;
*p = *q;
*q = temp;
p++;
q--;
}
}
void showArray(int* p, int n)
{
int i;
for(i = 0; i < n; i++)
{
printf("%d ",p[i]);
}
printf("\n");
}
int main()
{
int a[8] = {1,2,3,4,5,6,7,8};
showArray(a,8);
reverse(a,&a[7]);
showArray(a,8);
return 0;
}
练习:写一个函数,计算数组中成绩小于60的人数,要求数组定义在main函数中,不及格的人数,由返回值返回
5.值传递和地址传递
二者都是传递参数、值、数字的方法,有区别;在具体使用中要因地制宜
总结
主要学习了二维数组、指针、函数。 对二维数组的初始化、遍历二维数组及注意事项类比一维数组,深入浅出的讲解;函数的参数、返回值、命名规范以及类别进行了详细的阐述,并结合指针进行了编程练习,值传递和地址传递的区别