Skip to content

第三周作业答案

答案的视频讲解将会在基础阶段结束之后更新,预计11月中旬更新

  1. 描述一下什么是函数的声明和函数的定义?
函数定义可以描述一个函数的所有信息,包括返回值类型、函数名、函数的参数列表和函数体
函数声明为编译器提供了函数的基本信息,但不提供具体的实现细节,包括返回值类型、函数名、函数的参数列表再加分号
  1. 从变量的生存期、变量存储的位置和变量的作用域来说明全局变量和局部变量的区别。
全局变量:
生存期:从程序启动到程序结束
存储位置:数据段
作用域:从定义位置到文件的末尾均可见,所有函数可直接访问

局部变量
生存期:从进入作用域开始,离开作用域时销毁
存储位置:栈区里面的调用函数栈帧内部
作用域:仅作用域内部可见,外部不可访问
  1. 为什么下面代码当中,main函数里面的变量a不发生改变?
c
void func(int a){
    a = a + 1;
}
int main(){
    int a = 10;
    func(a);
    printf("a = %d\n", a);
    return 0;
}
因为C语言当中函数的参数以值传递的形式传递,所以调用func(a)时会将a的数值拷贝给被调函数,被调函数无论做任何修改,都不会影响到main函数里面的变量a
  1. C语言学习 | week03_分段函数_1知识点:函数
c
#include <stdio.h>
int f(int x){
    int y;
    if (x < 1){
        y = x;
    }
    else if (x < 10){
        y = 2 * x - 1;
    }
    else{
        y = 3 * x - 11;
    }
    return y;
}
int main(){
    int x; //这一题的输入和输出都是整数
    scanf("%d", &x);
	int y = f(x);
    printf("%d\n", y);
}
  1. C语言学习 | week03_分段函数_2知识点:函数
c
#include <stdio.h>
double f(double x){
    double y;
    if (x >= 0 && x < 2){
        y = 2.5 - x;
    }
    if (x >= 2 && x < 4){
        y = 2 - 1.5 * (x - 3) * (x - 3);
    }
    if (x >= 4 && x < 6){
        y = x / 2 - 1.5;
    }
    return y;
}
int main(){
    double x, y = 0;
    int m;
    scanf("%d", &m);
    for (int i = 0; i < m; ++i){
        scanf("%lf", &x);
		y = f(x);
        printf("y=%.1f\n", y);
    }
    return 0;
}
  1. C语言学习 | week03_正整数反转知识点:函数
c
#include <stdio.h>
int reverse(int num){
    //整体思路
    //假设num初始为1234
    //依次提取每位数字1、2、3、4
    //然后构造4321
    // curnum --> digit --> result
    // 1234 --> 4 --> 4
    // 123 --> 3 --> 43
    // 12 --> 2 --> 432
    // 1 --> 1 --> 4321
    int digit; //用来记录位数
    int curnum = num; //用来记录当前剩余num
    int result = 0;//用来记录反转中的结果
    while(curnum > 0){
        digit = curnum % 10;
        result = result*10 + digit;
        curnum = curnum/10;
    }
    return result;
}
int main(){
    int n,num;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i){
        scanf("%d", &num);
        printf("%d ", reverse(num));
    }
    printf("\n");
    return 0;
}
  1. C语言学习 | week03_计算距离知识点:函数(选做题)
c
#include <stdio.h>
#include <math.h>
double distance(int x1, int y1, int x2, int y2){
    double d, d1, d2, b;
    d1 = (x2 - x1) * (x2 - x1);
    d2 = (y2 - y1) * (y2 - y1);
    b = d1 + d2;
    d = sqrt(b);
    return d;
}
int main(){
    int n, m, k, i, a[100], b[100];
    double q, s;
    q = 0;
    scanf("%d", &n);
    for (i = 0; i < n; i++){
        scanf("%d", &a[i]); //记录第i点的x
        scanf("%d", &b[i]); //记录第i点的y
    }
    for (i = 0; i < n - 1; i++){
    //这里范围是n-1是因为每次要算两个点,最后一次是倒数第二个点和倒数第一点计算距离
        s = distance(a[i], b[i], a[i+1], b[i+1]);
        q = q + s;
    }
    printf("%.2lf", q);
    return 0;
}
  1. C语言学习 | week03_奇偶和知识点:函数
c
#include<stdio.h>
int even(int a){
    return a%2 != 0; //a为奇数返回真,a为偶数返回假
}
int main(){
    int a;
    int result = 0;
    while(scanf("%d", &a), a > 0){
        if(even(a)){
            result += a;
        }
    }
    printf("%d\n", result);
    return 0;
}
  1. 数组有哪些特点?[]运算符在定义语句和非定义语句作用分别是什么?
数组的特点:连续、有序、元素类型相同
  1. 数组中的元素arr[i]的地址如何计算?
address(arr[i]) = base_address(arr) + i * sizeof_element
  1. 一维数组作为函数参数传递的时候会丢失什么信息?
丢失数组长度的信息
  1. 二维数组arr[M][N]的本质是一个一维数组,这个一维数组有多少个元素,每个元素的类型是什么?arr[i][j]的地址是多少?为什么二维数组传递的时候,不能省略第二个维度?
arr[M][N]本质是一个一维数组,该数组长度为M,数组中的每个元素是长度为N的小数组。
address(arr[i][j]) = base_address + (i * cols_num) * sizeof_element + j * sizeof_element
在二维数组中如果需要访问某个元素,要求每个一维数组的长度必须是一致的。
  1. C语言学习 | week03_循环数组 知识点:数组
c
#include <stdio.h>
int main(){
	int a[100];
    int n,N;
	scanf("%d",&n);
	for (int i = 0; i < n; ++i){
		scanf("%d",&a[i]);
	}
	scanf("%d",&N);
    for (int j = N; j > 0; --j){
        int last = a[n - 1];//备份原来的最后一个元素
        for (int i = n - 1; i > 0; --i){
            //下标范围从n-1到1,依次用前面的元素覆盖后一个位置
            a[i] = a[i - 1];
        }
        a[0] = last;//将原来最后一个元素放到开始
    }
    for(int  i = 0; i < n; ++i){
        printf("%d ", a[i]);
    }
    printf("\n");
	return 0;
}
  1. C语言学习 | week03_统计分数 知识点:数组
c
#include<stdio.h>
int main(){
	int n;
	int i, j=0, k=0, l=0, f=0, h=0, b=0;
	int a[100];
	scanf("%d", &n);
	for(i=0; i<n; i++){
		scanf("%d", &a[i]);
		if(a[i]>=0 && a[i]<60){
			j++;
		}
		else if(a[i]>=60 && a[i]<70){
			k++;
		}
		else if(a[i]>=70 && a[i]<80){
			l++;
		}
		else if(a[i]>=80 && a[i]<90){
			f++;
		}
		else if(a[i]>=90 && a[i]<100){
			h++;
		}
		else if(a[i]==100){
			b++;
		}
	}
	printf("%d %d %d %d %d %d\n", j, k, l, f, h, b);
	return 0;
}
  1. C语言学习 | week03_有序插入 知识点:数组
c
#include <stdio.h>
int main(){
    int a[10];
    for(int i = 0; i < 9; ++i){
        scanf("%d", &a[i]);
    }//当前数组的下标范围是0~8
    int temp;
    scanf("%d",&temp);
    int j; //j需要定义在循环外面
    for(j = 8; j >= 0 && a[j] > temp; --j){
        //从后往前遍历数组,如果a[j]较大,则将其位置后移
        //如果代码是从前往后遍历,在后移的时候要注意备份原来后面的数据
        a[j + 1] = a[j];
    }
    //两种退出的可能性:要么temp最小,此时j为-1;要么temp大于a[j]
    a[j + 1] = temp;
    for(int i = 0; i < 10; ++i){
        printf("%d\n", a[i]);
    }
    return 0;
}
  1. C语言学习 | week03_找最大值 知识点:数组
c
#include <stdio.h>
int main(){
    int a[10];
    while (1)
    {
        for (int i = 0; i < 10; ++i){
            int ret = scanf("%d", &a[i]);
            if(ret == EOF){
                return 0;
            }
        }
        int max = a[0]; // 假设a[0]是当前最大值
        for (int i = 1; i < 10; ++i){
            max = max > a[i] ? max : a[i];
        }
        printf("max=%d\n", max);
    }
    return 0;
}
  1. C语言学习 | week03_合并有序数组 知识点:数组
c
#include <stdio.h>
int main(){
    int a[100], b[100], c[200];
    int i, j, m, n, k;
    while (scanf("%d", &m) != EOF){
        for (i = 0; i < m; i++){
            scanf("%d", &a[i]);
        }
        scanf("%d", &n);
        for (j = 0; j < n; j++){
            scanf("%d", &b[j]);
        }
        i = j = k = 0;
        while (i < m && j < n){ //先一个个合并,直到某一个数组所有元素全部都已合并
            if (a[i] <= b[j]){
                c[k++] = a[i++];
            }
            else{
                c[k++] = b[j++];
            }      
        }
        if (i < m){ // a有剩余 而b合并完了
            for (; i < m; i++, k++){
                c[k] = a[i];
            }
                
        }
        if (j < n){ // b有剩余 而a合并完了
            for (; j < n; j++, k++){
                c[k] = b[j];
            }
        }
        for (i = 0; i < k; i++){
          	if(i == 0){
              printf("%d", c[i]);
            }
            else{
              printf(" %d", c[i]); //这道题目末尾没有空格
            }
        }
        printf("\n");
    }
    return 0;
}
  1. C语言学习 | week03_冒泡排序 知识点:数组(选做题)
c
#include <stdio.h>
int main(){
    int n;
    int a[100000];
    scanf("%d", &n);
    for (int i = 0; i < n; ++i){
        scanf("%d", &a[i]);
    }
    for (int i = n - 1; i >= 1; --i){
        //先求最大,再求第二大 ... 最后求倒数第二大的
        for (int j = 0; j <= i - 1; ++j){
            // 从开始到边界进行冒泡
            if (a[j] > a[j + 1]){
                int temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
    for (int i = 0; i < n; i++){
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}
  1. C语言学习 | week03_方阵转置 知识点:二维数组
c
#include <stdio.h>
int main(){
    int n, a[101][101];
    while (scanf("%d", &n) != EOF){
        for (int i = 0; i < n; ++i){
            for (int j = 0; j < n; ++j){
                scanf("%d", &a[i][j]);
            }
        }
        for (int i = 0; i < n; ++i){
            for (int j = i + 1; j < n; ++j){
                int temp = a[i][j];
                a[i][j] = a[j][i];
                a[j][i] = temp;
            }
        }
        for (int i = 0; i < n; ++i){
            for (int j = 0; j < n; ++j){ //这道题行尾没有多余的空格
                if(j == 0){
                    printf("%d",a[i][j]);
                }
                else{
                    printf(" %d",a[i][j]);
                }
                
            }
            printf("\n");
        }
    }
    return 0;
}
  1. C语言学习 | week03_计算两个矩阵的乘积 知识点:二维数组
c
#include <stdio.h>
int main(){
    int a[2][3], b[3][2];
    int ans[2][2];
    while (scanf("%d%d%d", &a[0][0], &a[0][1], &a[0][2]) != EOF){
        scanf("%d%d%d", &a[1][0], &a[1][1], &a[1][2]);
        scanf("%d%d", &b[0][0], &b[0][1]);
        scanf("%d%d", &b[1][0], &b[1][1]);
        scanf("%d%d", &b[2][0], &b[2][1]);

        ans[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0];
        ans[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1];
        ans[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0];
        ans[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1];

        printf("%d %d\n", ans[0][0], ans[0][1]);
        printf("%d %d\n", ans[1][0], ans[1][1]);
    }
    return 0;
}