课堂笔记
数组
为什么需要数组
- 为解决大量同类型数据的存储和使用问题
- 为模拟现实世界
数组的分类
1.一维数组
- 定义
1.为n个变量连续分配储存空间
2.所有的变量数据类型必须相同
3.所以变量所占的字节大小必须相等 - 例子
int [5];
一维数组名不代表数组中的所有元素,
一维数组名代表数组第一个元素的地址 - 初始化
1.完全初始化
int a[5] = {1,2,3,4,5,};
2.不完全初始化(未初始化的元素自动为0)
int a[5] = {1,2,3};
3.不初始化(所有元素都是垃圾数)
int a[5];
4.清零
int a[5] ={0}; - 错误写法
错误写法:
int a[5];
a[5] = {1,2,3,4,5}; //错误
只有在定义数组的同时才可以整体赋值,其他情况下整体赋值都是错误的
int a[5] = {1,2,3,4, 5};
a[5] = 100; //error因为没有a[5]这个元素,最大只有a[4]
int a[5] = {1,2,3,4, 5};
int b[5];
如果要把a数组中的值全部复制给b数组错误的写法:
b = a;// error
正确的写法
for (i=0; i<5; ++i)
b[i] = a[i]; - 赋值
int main(void)
{
int a[5];
int i;
scanf("%d",&a[3]);
printf("a[3]=%d\n",a[3]);
scanf("%d",&a[4]);
printf("a[4]=%d\n",a[4]);
for ( i = 0; i < 5; ++i)
printf("%d ",a[i]);//剩余的a[0] a[1] a[2]没赋值就会打印出垃圾值
return 0;
}
输出结果
- 倒叙
# include<stdio.h>
int main(void)
{
int a[8] ={ 1,2,3,4,5,6,7,8};
int i ,j;
int t;
i = 0;
j = 7;
while (i<j)
{
t = a[i];
a[i] = a[j];
a[j] = t;
i++;
--j;
}
for (j=0;j<8;++j)//可以把j换为i
printf("%d\n",a[j]);
return 0;
}
2.二维数组
- int a[3][4];
总共是12个元素,可以当做3行4列看待 - 例子
int main(void)
{
int a[3][4]={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
int i ,j;
for (i=0;i<3;++i)
{
for (j=0;j<4;++j)
printf("%d ",a[i][j]);
printf("\n");
}
return 0;
}
其中 printf("\n"); 为换行的表达式
多维数组
- 是否存在多维数组
不存在
因为内存是线性一维的
n维数组可以当做每个元素是n-1维数组的一-维数组比如:
int a[3][4];
该数组是含有3个元素的一维数组
只不过每个元素都可以再分成4个小元素
int a[3][4][5];
该数组是含有3个元素的一维数组
只不过每个元素都是4行5列的二维数组
函数
为什么需要函数
1.避免重复操作
2.有利于程序的模块化
什么叫函数
逻辑上:能够完成特定功能的独立的代码块
物理上:1.能够接受数据(也可以不接受数据) 2.能够对接受的数据进行处理 3.能够将数据处理的结果返回
- 总结:函数是个工具,他是为了解决大量类似问题而设计的
如何定义函数
格式:
函数的返回值 函数的名称(函数的形参列表)
{
函数的执行体
}
- 函数的定义的本质是详细描述之所以能够实现某个特定功能的具体方法
- (return 表达式;) 的含义:
1.终止被调函数,向主调函数返回表达式的值
2.如果表达式为空,则只终止函数,不向被调函数返回任何值
3.break是用来终止循环和switch的,return是用来终止函数的
例子:
void f() (终止函数,不向被调函数返回任何值)
{
return;
}
int f() (终止函数,被调函数返回一个10)
{
return 10;
}
- 函数返回值的类型也称为函数的类型,如果因为中表达式的类型不同的话,则最终函数返回值的类型以函数名返回值类型为准(例子如下)
int f()//因为函数的返回值类型是int,所以最终f返回的是10而不是10.5
{
return 10.5;
}
int main(void)
{
int i =99;
double x =1.1;
x = f();
printf("%lf",x);
return 0;
}
函数的分类
- 有参函数和无参函数
- 有返回值函数和无返回值函数
- 库函数和用户自定义
- 值传递函数和地址传递函数
- 普通函数和主函数(main函数)
一个程序必须 有且只能有一个主函数
主函数可以调用普通函数
普通函数不能调用主函数
普通函数可以互相调用
主函数是程序的入口,也是程序的出口
函数注意问题
- 函数调用和函数定义顺序
如果函数的调用写在了函数定义的前面,则必须加函数前置声明
函数前置声明:
1.告诉编译器即将可能出现的若干个字母表达的是一个函数
2.告诉编译器即将可能出现的的若干字母所代表的函数的形参和返回值的具体情况
3.函数声明是一个语句,末尾必须加分号
4.对库函数的声明是通过 #include <库函数所在文件的名字.h>来实现的
形参和实参
1.个数相同;位置一一对应;数据类型必须相互兼容
2.同一个函数内不能重复定义一个数
常用的系统函数
可参考《turboc 2.0实用大全》
递归
参考视频
用函数来判断素数
int isprime(int val)
{
int i;
for (i=2;i<val;++i)
{
if (val%i==0)
break;
}
if (i == val)
return 1;
else
return 2;
}
int main(void)
{
int m;
do
{
printf("请输入:");
scanf("%d",&m);
if (isprime(m) == 1)
printf("yes\n");
else
printf("no\n");
}while (1);
return 0;
}
变量的作用域和储存方式
- 按作用域分
1.全局变量
在所有函数外部定义的变量叫全局变量
全局变量的使用范围:从定义位置开始到整个程序结束
2.局部变量
在一个函数内部定义的变量或者函数的形参 都统称为局部变量
void f(int)
{
int j = 20;
}
其中i和j都属于局部变量
注意:全局变量和局部变量命名冲突的问题:
在一个是函数内部如果定义的局部变量的名字和全局变量名一样时,局部变量会屏蔽掉全局变量
- 按变量的存储方式
1.静态变量
2.自动变量
3.寄存器变量
oj作业
第1题
int main(void)
{
char a, b, c, t;
while (scanf("%c%c%c%c", &a, &b, &c) != EOF)
{
if (a > b)
{
t = a;
a = b;
b = t;
}
if (a > c)
{
t = a;
a = c;
c = t;
}
if (b > c)
{
t = b;
b = c;
c = t;
}
printf("%c %c %c\n", a, b, c);
}
return 0;
}
解题思路:利用网课看的三个数互换来实现数的比较
第2题
# include<math.h>
int main()
{
int x1;
int x2;
int y1;
int y2;
double d;
double g;
do
{
printf("请输入两个点的坐标( , ) ( , )\n",x1,y1,x2,y2);
scanf("%d",&x1);
scanf("%d",&y1);
scanf("%d",&x2);
scanf("%d",&y2);
g = (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
d = sqrt(g);
printf("两点间的距离为%.2lf\n",d);
}while(1);
return 0;
}
截图思路:利用<math.h>和两点距离公式求出答案
第3题
# include<math.h>
int main()
{
int x1;
int x2;
int y1;
int y2;
double d;
double g;
do
{
printf("请输入两个点的坐标( , ) ( , )\n",x1,y1,x2,y2);
scanf("%d",&x1);
scanf("%d",&y1);
scanf("%d",&x2);
scanf("%d",&y2);
g = (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
d = sqrt(g);
printf("两点间的距离为%.2lf\n",d);
}while(1);
return 0;
}
解题思路,先定义三个变量,最后利用公式将球的体积表达出来再用do····while进行多次输出
第4题
int main(void)
{
double x;
double h;
do
{ printf("请输入数字:");
scanf("%lf",&x);
if (x>0)
printf("%.2lf\n",x);
else if (x<0)
{
h = -x;
printf("%.2lf\n",h);
}
} while (1);
return 0;
}
解题思路:先定义数,当x<0时 |x|=-x 当x>0时 |x|=x
第5题
int main(void)
{
float score;
do
{
printf("输入你的成绩\n");
scanf("%f",&score);
if (score>100)
printf("不可能\n");
else if (score>=90 && score<=100)
printf("A\n");
else if (score>=80 &&score<=90)
printf("B\n");
else if (score>=70 &&score<=80)
printf("c\n");
else if (score>=60 &&score<=70)
printf ("D\n");
else if (score>=0 &&score<=60)
printf("E\n");
}while (1);
return 0;
}
解题思路:定义成绩后依此分层输出
第6题
int main(void)
{
int a;
int b;
int c;
int x;
do
{
printf("请输入 年 月 日\n",a,b,c);
scanf ("%d",&a);
scanf ("%d",&b);
scanf("%d",&c);
switch (b)
{
case 1 :
x = c;
printf("%d天\n",x);
break;
case 2 :
x = 31 +c;
printf("%d天\n",x);
break;
case 3 :
x = 31 + 28 +c;
printf("%d天\n",x);
break;
case 4 :
x = 31 + 28 + 31 +c;
printf("%d天\n",x);
break;
case 5 :
x = c + 31 +28 +31 + 30;
printf("%d天\n",x);
break;
case 6 :
x = c +31 + 28 + 31 + 30 +31;
printf("%d天\n",x);
break;
case 7 :
x = c + 31 + 28 + 31 +30 + 31 + 30;
printf("%d天\n",x);
break;
case 8 :
x = c + 31 + 28 + 31 +30 + 31 + 30 + 31;
printf("%d天\n",x);
break;
case 9:
x = c + 31 + 28 + 31 +30 + 31 + 30 + 31 + 30;
printf("%d天\n",x);
break;
case 10 :
x = c + 31 + 28 + 31 +30 + 31 + 30 + 31 + 30 + 31;
printf("%d天\n",x);
break;
case 11:
x = c + 31 + 28 + 31 +30 + 31 + 30 + 31 + 30 + 31 + 30;
printf("%d天\n",x);
break;
default:
break;
}
}while(1);
return 0;
}
解题思路:用Switch算出每一个月的天数,再用do····while实现循环
第7题
{
int a;
int b;
while (1)
{
int sum = 1;
scanf("%d%d",&a,&b);
for (int i = a; i <=b; i++)
{
if(i%2!=0)
sum = sum * i;
}
printf ("%d\n",sum);
}
return 0;
}
解题思路:利用for函数来实现数的递加,利用if函数来判断是否为奇数,利用while函数来实现多次输入
(缺点:无法输入数的个数和具体是那些数)
第8题
int main(void)
{
int m, n, t;
int i;
while (1)
{ scanf("%d %d",&m,&n);
int sum1 = 0, sum2 = 0;
if (m > n)
{
t = m;
m = n;
n = t;
}
for ( i = m; i <= n; i++)
{
if (i % 2 == 0)
sum1 += i * i;
else
sum2 += i * i * i;
}
printf("%d %d\n", sum1, sum2);
}
return 0;
}
解题思路:用if来保证大数在后,利用for来实现偶数平方和相乘和奇数的立方再用while来循环此过程