Skip to content

第四周作业答案

答案会在下周更新的时候发布,视频讲解会于11月中旬更新

  1. 下面的代码为什么不能正常执行?
c
int main(){
	int *p;
  *p = 2;
} //这是典型的野指针问题,指针变量p里面没有合理的初始值,指向一个未知的位置
  1. 描述使用指针变量在被调函数中修改主调函数的数据的一般流程。
1、被调函数需要设计指针类型的形参
2、主调方在调用被调函数的时候需要传入数据的地址
3、被调函数的函数体里面需要使用间接访问(*或者[])的访问修改数据
  1. 指针和数组存在什么关联?数组名什么情况下可以当成指针来使用?数组名什么情况下不能当成指针来使用?
指针不是数组,数组也不是指针。指针可以使用[]运算符,数组在某些情况下会退化成指针。

当涉及 赋值、做加减法、作为函数实参传递 等场景的时候,数组名会退化成一个指针;
当涉及 sizeof、取地址 等场景的时候,数组名不能当成指针使用。
  1. 下标访问运算符和解引用运算符有什么关系吗?
p[i] 等价于 *(p+i)
  1. 使用函数和指针完成OJ题 C语言学习 | week04_指针传递
c
#include <stdio.h>
void compute(float a,float b,float *c,float *d); 
int main(){
    float a, b, c, d;
    scanf("%f%f", &a, &b);
    compute(a, b, &c, &d);
    printf("%g %g", c, d);
    return 0;
}
void compute(float a,float b,float *c,float *d){
    *c = a+b;
    *d = a-b;
}
  1. 使用函数和指针完成OJ题 C语言学习 | week04_求和
c
#include <stdio.h>
void  mySum(int *p,  int len,  int *sumOdd,  int *sumEven);
int main(){
    int n;
    scanf("%d", &n);
    int arr[101];
    for(int i = 0; i < n; ++i){
        scanf("%d", &arr[i]);
    }
    int sumOdd = 0;
    int sumEven = 0;
    mySum(arr, n, &sumOdd, &sumEven);
    printf("%d %d\n", sumOdd, sumEven);
    return 0;
}
void  mySum(int *p,  int len,  int *sumOdd,  int *sumEven){
    *sumOdd = 0;
    *sumEven = 0;
    for(int i = 0; i < len; ++i){
        if(p[i]%2 != 0){
            *sumOdd += p[i];
        }
        else{
            *sumEven += p[i];
        }
    }
}
  1. 使用函数和指针完成OJ题 C语言学习 | week04_找最大值
c
#include <stdio.h>
void search(int *pa, int n, int *pmax, int *pflag);
int main(){
    int arr[10];
    for(int i = 0; i < 10; ++i){
        scanf("%d", &arr[i]);
    }
    int max;
    int flag;
    search(arr, 10, &max, &flag);
    printf("Max is:%d\nMax position is:%d\n", max, flag);
    return 0;
}
void search(int *pa, int n, int *pmax, int *pflag){
    *pmax = pa[0];
    *pflag = 0;
    for(int i = 1; i < 10; ++i){
        if(pa[i] > *pmax){
            *pmax = pa[i];
            *pflag = i;
        }
    }
}
  1. C风格的字符串本质是一个字符数组,这个字符数组有什么特征?
c
在有效内容结束之后会紧跟一个'\0'字符
  1. 如何给字符串赋值?如何判断两个字符串是否相同?为什么不能用===运算符?
strcpy可以给字符串赋值
strcmp可以判断两个字符串是否相同
不能使用=运算符和==运算符的原因是C语言当中没有原生的字符串类型,C语言的字符串都依靠字符数组实现的,数组是不能够直接被=赋值或者用==进行比较的。
  1. 假设字符串的最后一个字符可能是换行符,怎么去掉?
c
// char str[1024] = xxxx 
if(str[strlen(str)-1] == '\n'){
	str[strlen(str)-1] = '\0';
}
  1. 什么说scanf是不安全的,而fgets是安全的?
scanf没有长度参数,当输入内容的有效长度超过了已经分配的内存空间大小时,会发生内存越界;
fgets有一个长度参数,可以限制单次输入的最大长度,这样可以避免数组越界问题。
  1. 自己实现strlen、strcpy和strcat函数的函数定义。
c
size_t myStrlen(char str[]) {
	size_t length = 0;
	for (int i = 0; str[i] != '\0'; ++i) {
		++length;
	}
	return length;
}
void myStrcpy(char to[], char from[]) {
	int i;
	for (i = 0; from[i]; ++i) {
		to[i] = from[i];
	}
	to[i] = '\0';
}
void myStrcat(char str1[], char str2[]) {
	int i, j;
	for (i = strlen(str1), j = 0; str2[j]; ++i, ++j) {
		str1[i] = str2[j];
	}
	str1[i] = '\0';
}
  1. OJ题 C语言学习 | week04_字符串排序输出
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
    char str1[100];
    char str2[100];
    char str3[100];
    fgets(str1,100,stdin);
    fgets(str2,100,stdin);
    fgets(str3,100,stdin);

    if (strcmp(str1, str2) > 0) {
        if (strcmp(str1, str3) > 0) {
            if(strcmp(str2,str3) > 0){
                printf("%s%s%s", str3, str2, str1);
            }
            else{
                printf("%s%s%s", str2, str3, str1);
            }
        }
        else {
            printf("%s%s%s", str2, str1, str3);
        }
    }
    else {
        if (strcmp(str2, str3) > 0) {
            if(strcmp(str1,str3) > 0) {
                printf("%s%s%s", str3, str1, str2);
            }
            else {
                printf("%s%s%s", str1, str3, str2);
            }
        }
        else {
            printf("%s%s%s", str1, str2, str3);
        }
    }
    return 0;
}
  1. OJ题 C语言学习 | week04_统计个数
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void calc(char *str, int *palp, int *pnum, int *pspa){
    *palp = 0;
    *pnum = 0;
    *pspa = 0;
    for(int i = 0; str[i] != '\0'; ++i){
        if(str[i] >= 'a' && str[i] <= 'z' || str[i] >= 'A' && str[i] <= 'Z'){
            ++*palp;
        }
        else if(str[i] >= '0' && str[i] <= '9'){
            ++*pnum;
        }
        else if(str[i] == ' '){
            ++*pspa;
        }
    }
}
int main(){
    char str[100];
    fgets(str,100,stdin);
    int alp = 0;
    int num = 0;
    int spa = 0;
    calc(str, &alp, &num, &spa);
    printf("%d %d %d\n", alp, num, spa);
    return 0;
}
  1. OJ题 C语言学习 | week04_高精度加法
c
#include <string.h>
#include <stdio.h>
void reverse(char *str){
    int i = 0, j = strlen(str) - 1;
    for (; i < j; ++i, --j){
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
}
void stradd(char *a, char *b, char *c){
    reverse(a); // 反转字符串 以便从个位开始计算
    reverse(b);
    int flag = 0;
    int a_longer_than_b = 0;
    if (strlen(a) > strlen(b)){
        a_longer_than_b = 1;
    }
    else{
        a_longer_than_b = 0;
    }
    int max_a_b = strlen(a) > strlen(b) ? strlen(a) : strlen(b);
    int min_a_b = strlen(a) > strlen(b) ? strlen(b) : strlen(a);
    int i = 0;
    for (; i < min_a_b; ++i) { // 先计算a和b都有的位
        int temp = a[i] - '0' + b[i] - '0' + flag;
        if (temp >= 10){
            c[i] = temp % 10 + '0';
            flag = 1;
        }
        else{
            c[i] = temp + '0';
            flag = 0;
        }
    }
    for (; i < max_a_b; ++i){ // 较小的数已经算完了,将另一个数的剩余部分加到结果中
        if (a_longer_than_b){
            int temp = a[i] - '0' + flag;
            if (temp >= 10){
                c[i] = temp % 10 + '0';
                flag = 1;
            }
            else{
                c[i] = temp + '0';
                flag = 0;
            }
        }
        else{
            int temp = b[i] - '0' + flag;
            if (temp >= 10){
                c[i] = temp % 10 + '0';
                flag = 1;
            }
            else{
                c[i] = temp + '0';
                flag = 0;
            }
        }
    }

    if (flag == 1) { // 考虑最后进位的情况
        c[max_a_b] = '1';
        c[max_a_b + 1] = '\0';
    }
    reverse(c);
}
int main()
{
    char a[102] = {0};
    char b[102] = {0};
    char c[102] = {0};
    fgets(a, 102, stdin);
    if (a[strlen(a) - 1] == '\n'){
        a[strlen(a) - 1] = '\0';
    }
    fgets(b, 102, stdin);
    if (b[strlen(b) - 1] == '\n'){
        b[strlen(b) - 1] = '\0';
    }
    stradd(a, b, c);
    printf("%s\n", c);
    return 0;
}