C语言学习笔记

1.静态变量,局部,外部变量等

        静态变量,用static限定修饰,是全局变量,生命周期是一整个应用程序的生命周期,非静态变量即没有用static限定修饰,是局部的,其生命周期是其所在类的生命周期

#include <stdio.h>

// 函数外定义变量 x 和 y
int x;
int y;

int addtwonum() {
    // 函数内声明变量 x 和 y 为外部变量
    // 给外部变量(全局变量)x 和 y 赋值
    extern int x ;
    extern int y ;
    x = 1;
    y = 2;
    return x + y;
}

int main() {
    int result;

    // 调用函数 addtwonum
    result = addtwonum();

    printf("result 为: %d", result);
    return 0;
}

2.常量的定义

        把常量定义为大写字母形式,是一个很好的编程习惯。

        const 数据类型 常量名 = 常量值;

        const int MAX_VALUE = 100;

        define 常量名 常量

        define PI 3.1415926

3.关于void

        1.不返回任何信息的函数原型为“void function(…);”。

一般主函数没有返回值,或者返回值默认为整数,所以一般直接定义成int main()。所以把main函数定义成void main()这种做法是错误的!

        2.但是int main(void)是可以的,是正确的,因为表示的是函数没有参数,是可以的

4.getchar的运用

#include<stdio.h>
int main(void) {
    int guess = 1;
    printf("is your number %d\n", guess);
    while (getchar() != 'y') {
        if (getchar() == 'n') {
            printf("Well,is it %d\n", ++guess);
        }
        else {
            printf("Sorry,I understand only y or n.\n");
        }
        while (getchar() != '\n')
            continue;
    }
    printf("i known you can do it\n");
    return 0;
}

        这段代码本来是希望在下面这步能实现while (getchar() != '\n')//不管是不是换行符都会继续判断,即不受换行符的影响,也可以接受很长的判断符,比如no,nnnnn等,而不是只能用n判断

        但是犯了个低级错误,getchar函数每次只能输入一个字符。

        在 while 循环中,第一次调用 getchar() 用来检查用户输入的字符是否为 'y'。如果不是 'y',则进入 if 分支。在 if 分支中,你再次调用 getchar() 来获取用户的输入字符。这里的问题在于,第一次调用 getchar() 获取了一个字符进行比较,但第二次调用 getchar() 并不会获取刚才用户输入的 'n',而是会获取下一个字符(用户输入的下一个字符)。

        例如,如果用户输入 "no",那么第一次调用 getchar() 获取 'n',然后进入 if 分支。但在 if 分支中,第二次调用 getchar() 会获取 'o',而不是 'n'。因此,代码并不会按照预期工作。

        要解决这个问题,你可以修改代码,使其只调用一次 getchar() 并保存其返回值,然后在需要的地方使用保存的值进行比较。

修改如下:

#include<stdio.h>
int main(void) {
    int guess = 1;
    char response;
    printf("is your number %d\n", guess);
    while ((response=getchar()) != 'y') {
        if (response == 'n') {
            printf("Well,is it %d\n", ++guess);
        }
        else {
            printf("Sorry,I understand only y or n.\n");
        }
        while (getchar() != '\n')//再次调用getchar读取下一位字符
            continue;
    }
    printf("i known you can do it\n");
    return 0;
}

        这里我一开始又犯了一个错误,while ((response=getchar()) != 'y'),我一开始写错成了while(response=getchar()!= 'y'),这里犯了一个逻辑运算优先级的问题,不等于号的优先级大于等于号,所以导致不能达到预期效果。

        注意这里判断是不是n这个语句的好处是可以增加printf("Sorry,I understand only y or n.\n");这个语句,对于一个应用程序来说比较严谨,规范完整。

5.清空缓冲区,以规避一些换行符的问题

while (getchar() != '\n') // 清空输入缓冲区
            continue;

详细的解释,好好理解即可:

  1. getchar()函数: getchar()是一个标准C函数,用于从标准输入(通常是键盘)读取一个字符。它会返回读取到的字符。

  2. while (getchar() != '\n')的意义: 这行代码的意思是,循环读取字符,直到读取到换行符('\n')为止。换行符通常表示用户输入的结束,特别是在使用回车键提交输入时。

  3. 循环执行过程:

  • 当用户在程序等待输入时,每次输入一个字符。

  • 如果输入的字符不是换行符('\n'),getchar()将继续等待并读取下一个字符。

  • 一旦读取到换行符('\n'),循环条件getchar() != '\n'不成立,循环结束。

  1. 影响到最外层循环的执行:
  • 一旦内部的while循环结束(即读取到了换行符),控制流会继续执行下一个语句,通常是回到最外层的主循环或者继续执行主程序的下一步骤。

  • 这样做的目的通常是确保输入缓冲区中不留下任何未处理的字符,从而避免这些字符影响程序的后续输入读取或其他操作。

1.scanf和getchar

        注意scanf会跳过换行符和空格还有制表符,但是getchar是真的不能跳过这些东西,所以小心。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void display(char ch, int rows, int cols);
int main(void) {
    int ch;
    int rows, cols;
    while ((ch = getchar()) != '\n') {
        if (scanf("%d %d", &rows, &cols) != 2)
            break;
        display(ch, rows, cols);
        while (getchar() != '\n')
            continue;
    }
    return 0;
}
void display(char ch, int rows, int cols) {
    for (int i=0; i < rows; i++) {
        for (int j=0; j < cols; j++) 
            putchar(ch);
        putchar('\n');
    }
}

2.scanf编译器报错

        #define _CRT_SECURE_NO_WARNINGS    VS的编译器就是得加这个不然scanf报错说什么function unsafe 之类的     

3.留意putchar的用法

        加上那个while循环清空缓冲区就是因为想要实现多组输入的时候会发现第二组还没开始输入就自动退出,结束程序了,这是因为每组结束都有换行符,而这个换行符被scanf跳过了,但是getchar不会跳过,它就直接读取到了换行符,就直接不符合循环条件,程序结束。所以要在scanf后面加一个清空换行符的操作。

4.scanf的返回值

        在if语句中,用break,可以在scanf的返回值不是2时结束程序,即如果一个或者两个输入值不是整数或者遇到文件结尾就终止程序。

解释:

  1. 返回值
  • scanf 函数的返回值是成功读取并赋值的参数个数。
  1. 返回值比较:
  • scanf 函数成功读取并分配了两个整数时,返回值为 2,因为成功赋值了两个变量。

  • 因此,if (scanf("%d %d", &rows, &cols) != 2) 这行代码会判断 scanf 函数的返回值是否不等于 2。如果不等于 2,意味着 scanf 没有成功读取到两个整数,可能是因为输入格式不符合要求(比如输入的是一个整数或者其他类型的数据),或者输入流结束了。

6.递归和倒序,进制转换

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void to_binary(unsigned long n);
int main() {
    unsigned long number;
    while (scanf("%lu", &number) == 1) {
        to_binary(number);
        putchar('\n');
    }
    printf("Done.");
    return 0;
}
void to_binary(unsigned long n) {
    int r;
    r = n % 2;//9%2=1,4%2=0,2%2=0,1%2=1
    if (n >= 2)//9,4,2
        to_binary(n / 2);//4,2,1
    putchar(r == 0 ? '0' : '1');//1,0,0,1
    return;
}
  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值