美文网首页
C语言知识点

C语言知识点

作者: irenb | 来源:发表于2020-12-20 13:47 被阅读0次

    第一部分:C语言知识点

    1. C语言的官方标准

    • ANSI C / C89标准:1989年,美国国家标准协会(ANSI)发布了第一个官方标准(简称 C89标准 或 ANSI C)。
    • C99标准:1999年,国际标准化组织(ISO)和国际电工委员会(IEC)发布了C语言的新标准。
    • C11标准:2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)再次发布了C语言的新标准。

    2. C语言程序的运行过程

    • 编译:编译是由编译器来执行的,主要做的是语法检查工作;将C源程序翻译成计算机能识别的0和1;编译会把.c后缀的文件生成.o后缀的目标文件。
    • 链接:将编译好的.o目标文件和C程序库函数组合在一起,生成可执行文件(即.exe后缀的文件)。
    • 运行:直接双击打开.exe文件

    3. 变量

    概念:是内存中的一片空间,用来存放经常变化的数据。

    • 代码示例1:
    #include <stdio.h>
    
    int main() {
        // 1.定义变量(即在内存中开辟一块空间,空间的大小跟定义的类型有关,空间的名字就是变量名)
        int age;// 这一行代码就在内存中开辟一块4个字节的存储区域,它名字叫age;这块存储区域是用来存放int类型的数据的
        // 2.初始化:变量第一次赋值称为初始化。
        age = 22; //这行代码是把22,放到名字为age的这块存储区域中
        return 0;
    }
    
    • 代码示例2:
    #include <stdio.h>
    
    int main() {
        int a; // 定义一个变量:a是变量名,int是变量的类型
        // 定义一个变量,未初始化;a的值的可能性:1) 系统的数据;2) 上一个程序遗留的数据;3) 垃圾数。
        printf("a=%d\n", a); // a=1606422582,垃圾数据。
        // 初始化:就是清空(赋初值,0/NULL)的意思,清理一些垃圾数据。
        a = 10; // 将10保存到a中,第一次赋值相当于初始化
        a = 20; // 将20保存到a中,以后就叫给变量赋值
        int b = 30; // 定义变量的同时初始化
        printf("b=%d\n", b);
        return 0;
    }
    
    • 变量类型:分为字符型char、整数型int、浮点型float/double、指针、结构、联合等类型。
    • 变量的作用域
      局部变量(内部变量):在函数的内部或者代码块的内部定义的变量。
    • 代码示例:
    #include <stdio.h>
    
    int main() {
        int age = 20;
        //代码块代表一个空间,与age的空间并列
        {//代码块开始
            int a = 5;
            printf("a=%d\n", a); //a=5
            int age = 25; //在代码块内部可以定义和代码块外部同名的变量
            printf("age=%d\n",age); //age=25;
        }//代码块结束(此时代码块内部所有的空间会释放)
        printf("age=%d\n", age);//age=20;
        return 0;
    }
    
    • 变量分析题:(注意变量的作用域)


    • 变量的命名:命名需要符合标识符语法要求。
      ① 必须以 字母下划线 开头(注意:不能以数字开头)
      ② 包含 字母下划线数字
      ③ 大小写敏感的
      ④ 不能与 关键字 冲突
      ⑤ 标识符理论上讲,长度无限制,但太长了会被编译器截断

    • 变量的存储:
      ① 变量所占的存储空间(字节数):跟变量的类型和编译器环境有关。
      ② 变量存储单元的第一个字节的地址就是该变量的地址(详细地址/首地址)
      ③ 任何变量在内存中都是以二进制的形式存储:一个负数的二进制形式,其实就是对它的正数的二进制形式进行取反再加1。



    • 【了解】变量在内存中怎么储存?(变量为什么要有类型)
      ① 只要定义变量,系统就会开辟一块存储空间给我们的变量存储数据
      ② 越先定义的变量,内存地址越大(从字节地址最大的开始找)
      ③ 内存寻址是从大到小,高位放在高字节上,低位放在低字节上
      ④ 变量的地址就是变量所占的存储空间最小的字节地址(即首地址:&变量名称)
       计算机中最小储存单元是字节,每个字节都有一个地址。


    4. 常量

    • "量"表示数据。常量,则表示一些固定的数据,也就是不能改变的数据。
    • 定义常量的方法:const int a=100;
    • 易错示例:
    10.1;// 双精度 double
    5.2f; //单精度 float(注意:与double类型进行区分,小数点后面有 f 才表示是 float 类型,否则是 double 类型)
    
    // 字符型常量(易考点:要注意下面几种写法)
    'a'; // 正确写法:占用一个字符
    'ab'; // 错误写法:不是单个字符
    '李'; // 错误写法:因为一个汉字占2个字符
    '\n'; // 正确写法:因为转义字符,表示单个字符
    
    // 字符串常量(注意:字符串常量结尾默认都有一个'\0')
    "a"; // 占用两个字符,结尾有一个'\0';
    "中国"; // 占用 4 + 1 = 5 个字符;一个汉字占用两个字符,'\0'占用一个字符
    

    【掌握】常用ASCII值: 'A'== 65 、 'a' == 97 、 '0' == 48

    5. printf 函数

    • printf函数称为格式输出函数,其关键字最末一个字母f即为“格式”(format)之意
    • 代码示例:
    #include <stdio.h>
    
    int main() {
        int hour = 2, minute = 6;
        printf("%d:%d\n", hour, minute); // 2:6
        // %02d 表示输出的数字宽度为2,如果宽度不够就用0补齐左边
        printf("%02d:%02d\n", hour, minute); // 02:06
    
        float value = 3.14f;
        // %f 默认会保留6位小数
        printf("%f\n", value);//3.140000
        // 指定保留多少位小数: %.nf, 其中n就是需要保留多少位小数
        printf("%.2f\n", value);//3.14
        return 0;
    
        /*
          知识点1:指定位宽
            %0nd:在%与d之间,0n,n表示输出的数字的宽度,如果不够就用0补齐左边【重点】
            %nd:在%与d之间n,n表示输出的数字的宽度,如果不够就用空格补齐左边
            %-nd:在%与d之间 -n,n表示输出的数字的宽度,如果不够就用空格补齐右边
        
          知识点2:指定位数
           %m.nf:在%与f之间,可以有m.n,m表示输出数字所占的宽度,m表示小数点后面的位数,如果不够会用空格补齐左边
       */
    }
    
    • 格式控制符:


    • 其它知识点:

    //  printf函数打印 % 字符要用 %% 才能打印
    printf("5%%2=%d\n",5%2);//结果为:5%2=1
    

    &是C语言中的一个地址运算符,可以用来获取变量的地址
    &可以获取变量的地址,例如:&num
    *可以根据地址数据找到变量,例如:*(&num)

    6. scanf 函数

    scanf函数是一个阻塞式函数,程序会停在scanf函数出现的地方,直到接收到数据才会执行后面的代码。

    //  使用scanf接收用户从键盘上输入
    scanf("%d", &a);//注意: 必须告诉scanf函数变量的详细地址, 才能存储用户输入的数据
    //  %与d之间可以有数字n,这个n表示接受数据的宽度
    scanf("%2d",&a);
    
    • scanf 函数要点:
      ① 键盘输入的数据与格式化字符串中的要匹配, 不匹配时scanf函数就会自动终止。
      ② scanf接收多个数据时,为了防止出错一般加一个分隔符(例如:逗号或空格)
      (空格、回车、Tab可以做%c除外的分隔符,因为空格、回车、Tab是字符)
      ③ 不能在scanf的格式化字符串末尾写上\n。
      比如:scanf("%d\n", &a); 这将导致scanf函数无法结束。


    7. 运算符

    • 算术运算符:+、-、*、/、%
      【掌握】% 取模(取余)运算符的注意事项:
      ① 取模运算符的操作数只能是整数(5%3=2;)
      ② 余数的符号与最前面的被除数一致(-5%3=-2; 5%-3=2; -5%-3=-2)
      ③ 如果取模运算的左边小于右边, 那么结果就是左边(2%9=2;)
    • 自增自减写在前面和后面的区别:
      ① 如果++写在变量的前面, 那么会先将变量自增再用自增之后的结果参与运算
      ② 如果++写在变量的后面, 那么会先将变量的值参与运算再将变量自增
      ③ 总结一句话: ++在前, 先自增再运算, ++在后, 先运算再自增
     int b = ++a;  //等价于 a=a+1;  b=a;
     int b = a++; //等价于 b=a;  a=a+1;
    //【掌握】运算规则:先左++,再赋值,最后右++。
    
    • sizeof()运算符:sizeof可以用来计算 一个变量一个常量 、或 一种数据类型 所占的内存字节数。
    • 代码示例:
    #include <stdio.h>
    
    int main() {
        char c='a';
        printf("%d, %d\n", sizeof(10), sizeof(c)); //4, 1
        printf("%d, %d\n", sizeof 10, sizeof c); //4, 1
        printf("%d\n", sizeof(int)); //4
        return 0;
    }
    
    • 逻辑运算符:&& 逻辑与 、|| 逻辑或 、! 逻辑非
      【掌握】&& 和 || 都具有短路特征:如果前一个表达式能决定最终结果则不会计算后一个表达式。
    • 代码示例:
    #include <stdio.h>
    
    int main() {
        // 逻辑运算符 && 和 || 的短路特征
        int a=3,b=4,c=5,r;
        r=(a>b)&&(++b>c); // 因为 (a>b) 为假;所以 && 后面的表达式不管是真还是假,最终结果也一定是假。根据短路特征,&& 后面的表达式会自动忽略不参与计算。
        printf("%d,%d,%d,%d\n", a, b, c, r); //3, 4, 5, 0
        r=(a<b++)||(b<c++);
        printf("%d,%d,%d,%d\n", a, b, c, r); //3, 5, 5, 1
    
        // 非短路的逻辑运算符 & 和 |
        a=3;b=4;c=5;
        r=(a>b)&(b>++c);
        printf("%d,%d,%d,%d\n", a, b, c, r); //3, 4, 6, 0
        r=(a<b)|(b<c++);
        printf("%d,%d,%d,%d\n", a, b, c, r); //3, 4, 7, 1
        return 0;
    }
    

    8. 进制

    • 进制:是一种计数的方式,数值的表示形式
      ① 十进制:逢十进一 (如:13 == 1 * 10 + 3)
      ② 八进制:逢八进一 (如:15 == 1 * 8 + 5)
      ③ 二进制:逢二进一 (如:1101 == 1 * 2 * 2 * 2 + 1 * 2 * 2 + 0 * 2+ 1)
      ④ 十六进制:逢十六进一 (0 ~ 9 A ~ F d == 13)
    • 常见的进制转换
      10进制 转 2进制:除2取余法,把10进制数除以2,然后取得余数的序列,再倒序。
      例如:将十进制(97)转换为二进制数(1100001)

      2进制 转 10进制:所有位的位权相加:101=120+021+1*22
      2进制 转 16进制:4合1法。把一个二进制数,整数部分从右向左(小数部分从左向右)4位结合成1位,不足部分补0。

      16进制 转 2进制:1拆4法,16进制的1位拆成二进制的4位。

      2进制 转 8进制:3合1

    第二部分:C语言编程练习

    1. 加减乘除计算器

    /**  加减乘除计算器 (提示:录入1+2输出1+2=3)*/
    int test() {   
        int num1,num2; //定义两个变量,表示操作数
        char operator; //定义一个char类型变量,表示要进行操作
        printf("请按照如下格式录入(1 + 1)\n"); //提示用录入
        scanf("%d %c %d", &num1, &operator, &num2);
        int result;
        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                if (num2 == 0) {
                    printf("除数不能为零\n");
                    return 0;
                }
                result = num1 / num2;
                break;
    
            default:
                printf("你录入格式错误\n");
                break;
        }
        printf("%d %c %d = %d\n", num1, operator, num2, result);
        return 0;
    }
    

    2. 编写程序,要求从键盘键入n, 求 1/3+2/4+3/5+...+n-2/n的值

    #include<stdio.h>
    
    void main() 
    {
        int n = 0;
        double sum = 0;
        scanf("%d", &n);
    
        for (int i = 3; i <= n; i++)
        {
            sum += (double)(i - 2) / i;
        }
    
        printf("%lf\n", sum);
    }
    

    3. 输入一个年份,判断该年是否为闰年,若为闰年则输出“yes”,否则输出“no”。

    #include<stdio.h>
    
    void main() 
    {
        int year = 0;
        printf("请输入一个年份:");
        scanf("%d", &year);
        // 能被4整除,且不能被100整除;或者能被400整除
         if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){
            printf("yes\n");
        } else {
            printf("no\n");
        }
    }
    

    4. 从键盘输入3个数,将其从小到大排序后输出

    #include<stdio.h>
    #define ARR_LEN 3 // 数组长度为3
    
    void main() 
    {
        int arr[ARR_LEN] = { 0 };
        int temp = 0;
    
        // 读入三个数
        for (int i = 0; i < ARR_LEN; i++)
        {
            printf("请输入第%d个数的值:", i + 1);
            scanf("%d", &arr[i]);
        }
    
        // 排序
        for (int i = 0; i < ARR_LEN - 1; i++)
        {
            for (int j = 0; j < ARR_LEN - 1 - i; j++)
            {
                if (arr[j] > arr[j + 1])
                {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    
        // 输出结果
        for (int i = 0; i < ARR_LEN; i++)
        {
            printf("arr[%d] = %d\n", i, arr[i]);
        }
    }
    

    5. 从键盘输入两个数,交换两个数的值,再输出至屏幕

    #include<stdio.h>
    
    void main() 
    {
        int a = 0;
        int b = 0;
        int temp = 0;
    
        printf("请输入两个整数:");
        scanf("%d%d", &a, &b);
    
        printf("交换之前的值是:a=%d, b=%d\n", a, b);
    
        temp = a;
        a = b;
        b = temp;
    
        printf("交换后的值是:a=%d, b=%d\n", a, b);
    }
    

    6. 编写一个函数,通过指针实现两个数的交换

    #include<stdio.h>
    
    void swap(int *pa, int *pb)
    {
        int temp = 0;
        temp = *pa;
        *pa = *pb;
        *pb = temp;
    }
    
    int main()
    {
        int a = 3;
        int b = 5;
        int *pa = &a;
        int *pb = &b;
        void(*pswap)() = swap;
    
        // 交换之前
        printf("交换之前 a=%d, b=%d\n", a, b);
    
        // 交换
        pswap(pa, pb);
    
        // 交换之后
        printf("交换之后 a=%d, b=%d\n", a, b);
    
        return 0;
    }
    

    7. 输入一串字符,统计其中的字母、空格、数字及其他字符的个数

    #include<stdio.h>
    #define STR_LEN 100
    
    int main()
    {
        char str[STR_LEN] = { '\0' };
        int alpha = 0;
        int blank = 0;
        int digit = 0;
        int other = 0;
    
        // 输入一串字符
        printf("请输入一个字符串:\n");
        gets_s(str, STR_LEN);
    
        // 计算每种类型的字符的个数
        for (int i = 0; i < STR_LEN && str[i] != '\0'; i++)
        {
            if (('a' <= str[i] && str[i] <= 'z') || ('A' <= str[i] && str[i] <= 'Z'))
            {
                alpha++;
            }
            else if ('0' <= str[i] && str[i] <= '9')
            {
                digit++;
            }
            else if (str[i] == ' ')
            {
                blank++;
            }
            else
            {
                other++;
            }
        }
    
        // 输出统计的结果
        printf("字母有 %d 个\n空格有 %d 个\n数字有 %d 个\n其他有 %d 个\n", alpha, blank, digit, other);
        return 0;
    }
    

    8. 求最大公约数

    /** 1.【掌握】直接遍历法 */
    int maxCommonDivisor(int a, int b) {
        int max = 0;
        for (int i = 1; i <=b; i++) {
            if (a % i == 0 && b % i == 0) {
                max = i;
            }
        }
        return max;
    }
    /** 2.辗转相除法 */
    int maxCommonDivisor(int a, int b) {
        int r;
        while(a % b > 0) {
            r = a % b;
            a = b;
            b = r;
        }
        return b;
    }
    
    // 扩展:如何求最小公倍数
    // 最小公倍数 = (a * b)/最大公约数
    

    9. 冒泡排序

    冒泡排序是从小到大排序,可以形象的理解为:水中的气泡从下往上冒出,越往上气泡越大,即冒泡排序是从小到大排序。

    /** 
     *   【冒泡排序】:相邻元素两两比较,比较完一趟,最值出现在末尾
     *   第1趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第n个元素位置
     *   第2趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第n-1个元素位置
     *    ……   ……
     *   第n-1趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第2个元素位置 
     */
    void bublleSort(int *arr, int length) {
        for(int i = 0; i < length - 1; i++) { //趟数
            for(int j = 0; j < length - i - 1; j++) { //比较次数
                if(arr[j] > arr[j+1]) {
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            } 
        }
    }
    

    相关文章

      网友评论

          本文标题:C语言知识点

          本文链接:https://www.haomeiwen.com/subject/zbcknktx.html