• C语言入门


    库函数

    C语言本身提供给我们的函数;

    整型长度(字节):

    	char      -> 1
    	short     -> 2
    	int       -> 4
    	long      -> 4/8
    	long long -> 8
    	float	  -> 4
    	double	  -> 8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    计算机中的单位bit->比特位

    short age = 20;//向内存申请2个字节-16bit位,用来存放20;

    C语言规定只要sizeof(long) >= sizeof(int)就可以了,并没有规定说long的长度一定是4或者8;

    变量

    • 1.当局部变量名与全局变量名一致时,在函数内部优先使用局部变量;建议局部变量名和全局变量名不相同;
    • 2.全局变量的作用域是整个工程;

    变量的生命周期

    变量的生命周期是指变量创建到销毁的一个时间段;

    1.局部变量的生命周期:进入作用域生命周期开始,出作用域生命周期结束;
    2.全局变量的生命周期:整个程序的生命周期;

    放在大括号内的都是局部变量;
    
    • 1

    & 取地址

    scanf_s()输出函数

    问题1根据提示 scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

    • 1.在文件顶部第一行加入一行:#define _CRT_SECURE_NO_WARNINGS
    • 2.使用scanf_s,而不是scanf;

    scanf是C语言提供的
    scanf_s不是标准C语言提供的,是VS编译器提供的,一般不建议使用scanf_s();scanf_s没有跨平台性和移植性;

    文件创建时添加申明

    app\Common7\IDE\VC\VCProjectItems\newc++file.cpp
    #define _CRT_SECURE_NO_WARNINGS 1

    extern申明外部符号

    常量

    字面常量

    • const修饰的常变量,常量不可变; const int num = 9;
      常变量:本质是变量,但是有常量的属性;

      int arr[length] = {0};会报错"表达式必须含有常量值",数组定义只能为int arr[10] = {0};

    • #define定义的标识符常量
    #define MAX 10;
    int arr[MAX] = {0};//并没有报错,说明是常量;
    
    • 1
    • 2
    • 枚举常量
    enum Gender {
    	MALE,
    	FEMALE,
    	SECRT
    };
    enum Sex s = FEMALE;
    printf("%d\n\t", s);		//1
    printf("%d\n\t", MALE);		//0
    printf("%d\n\t", SECRT);	//2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    字符串+转义字符+注释

    字符串的结束标志是一个\0的转义字符。在计算字符串长度的时候\0是结束标志,不算作字符串内容,不管\0后面有没有值都不做处理。

    char chars[] = "abc";//数组
    
    • 1

    在这个chars变量的内容是'a','b','c','\0';其中'\0'的意思是字符串的结束标志,而'\0'的值是0;

    printf("%s\n", chars);
    
    • 1
    输出
    abc
    
    • 1
    char chars[] = {'a','b','c'};//数组
    printf("%s\n", chars);
    
    • 1
    • 2
    输出
    abc烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫虜惀?
    
    • 1
    分析

    为什么会出现乱码? 程序在输出数组chars的内容时因为没有\0,字符c后面是随机值,一直等遇到\0程序才输出结束;而\0的意思是,如果主动添加\0,程序就会正常输出;

    char chars[] = {'a','b','c','\0'};//数组
    printf("%s\n", chars);
    
    • 1
    • 2
    输出
    abc
    
    • 1

    转义字符

    转变原来的意思

    转义字符释义
    \?在书写连续多个问号时使用,防止他们被解析成三个母词(??+))
    \’表示用于字符常量'
    \"标识一个字符串内部的双引号
    \\用于表示一个反斜杠,防止它被解释为一个转义序列符
    \a警告字符,蜂鸣(系统提示音)
    \b退格符
    \f进纸符
    \n换行
    \r回车
    \t水平制表符
    \v垂直制表符
    \dddddd表示1~3个八进制的数字。如: 130X;作为8进制代表的那个十进制数字,作为ASCII码值对应的字符,比如 \32 是八进制,转换为十进制就是26,对应的ASCII字符为
    \xdddd表示2个十六进制数字。如:\x255

    异或

    计算规律:对应的二进制位相同,则为0;对应的二进制位相异,则为0;

    公式

    a^b=(!a&b)|(a&!b)

    复合赋值符

    +=
    -=
    *=
    %=
    /=
    *=
    >>=
    <<=
    |=
    ^=
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    单目操作符

    !		逻辑反操作(C语言中表示真假:0-;0-)
    -		负值
    +		正值
    &		取地址
    sizeof	操作数的类型长度(以字节为单位)
    ~		对一个数的二进制按位取反
    --		前置、后置--
    ++		前置、后置++
    *		间接访问操作符(解引用操作符)
    (类型)	强制类型转换	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    只要是整数,内存中存储的都是二进制的补码;
    原码 反码 补码;
    原码=补码-1取反;
    反码=补码-1;

    int a = 10;
    int b = a++;
    printf(" a=%d ,b=%d\n", a, b);
    
    • 1
    • 2
    • 3

    a++是后置++,先用后加,所以b=10,a=11;

    int a = 10;
    int b = ++a;
    printf(" a=%d ,b=%d\n", a, b);
    
    • 1
    • 2
    • 3

    ++a是前置++,先加后赋值,所以a=11,b=11;

    &&

     int a = 10;
     int b = 5;
     int c = a && b;
     printf("%d\n", c);
    
    • 1
    • 2
    • 3
    • 4

    在逻辑运算中,假:0;真:非0;

    EOF

    end of file:文件结束标志,值为-1

    逗号表达式

    exp1,exp2,exp3,exp4,...expN
    
    • 1

    ()

    函数调用操作符(调用方法时的方法括号)

    常见关键字

    auto 自动变量

    auto int a = 10;//局部变量;在作用域内自动创建,自动销毁;默认省略auto;
    
    • 1

    register 寄存器

    计算机存储数据:寄存器->高速缓存->内存->硬盘

    register int a = 10;//建议把a定义为寄存器变量;
    
    • 1

    signed 有符号

    可以存放正数或复数,当定义一个整型变量的时候,默认是signed的;默认省略。

    unsigned 无符号

    只可以存放正数;

    unsigned int a = -1;
    printf("%u\n", a);
    
    • 1
    • 2

    输出结果

    4294967295
    
    • 1

    extern 外部变量申明

    typeof 类型定义(类型重定义)

    unsigned int num = 20;
    //使用typeof重新定义
    typeof unsigned int u_int;
    u_int num = 20;
    
    • 1
    • 2
    • 3
    • 4

    关键字static

    static是用来修饰变量和函数;

    • 修饰局部变量-静态局部变量:局部变量的生命周期延长
      每调用一次testMethod函数,num局部变量加1
    #define _CRT_SECURE_NO_WARNINGS 1
    #include
    #include
    
    
    void testMethod() {
    
       int num = 0;//静态的局部变量
       num++;
       printf("%d\n", num);
    }
    int main() {
    
       int i = 0;
       while (i < 5 ) {
           i++;
           testMethod();
       }
       return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    程序输出结果:

    1
    1
    1
    1
    1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    程序分析:
    局部变量num 的生命周期随着函数testMethod的结束而结束,导致每次调用testMethod函时,局部num都输出1。如果想输出累加的效果,则需要将局部变量num的生命周期延长,这时就用到了static关键字。C2371

    #define _CRT_SECURE_NO_WARNINGS 1
    #include
    #include
    
    
    void testMethod() {
    
      static int num = 0;//静态的局部变量
      num++;
      printf("%d\n", num);
    }
    int main() {
    
      int i = 0;
      while (i < 5 ) {
          i++;
          testMethod();
      }
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    程序输出结果:

    1
    2
    3
    4
    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 修饰全局变量-静态全局变量

    改变了变量的作用域,–让静态的全局变量只能在自己所在的源文件内部使用。出了源文件就没法再使用了。

    constant.c

    #define _CRT_SECURE_NO_WARNINGS 1
    int age = 18;
    
    • 1
    • 2

    Hello.c

    #define _CRT_SECURE_NO_WARNINGS 1
    #include
    #include
    
    int main() {
     
        extern int age;
        printf("%d\n", age);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    程序输出结果

    18
    
    • 1

    如果给源文件Constant.c中的agestatic修饰呢?
    constant.c

    #define _CRT_SECURE_NO_WARNINGS 1
    static int age = 18;
    
    • 1
    • 2

    程序输出结果

    LNK2001:无法解析的外部符号age
    
    • 1

    程序分析

    从运行结果来看,给全局变量增加static关键字会使该变量的作用域降低。就有该结论: 改变了变量的作用域,—让静态的全局变量只能在自己所在的源文件内部使用。出了源文件就没法再使用了。

    • 修饰函数-静态函数

    static修饰函数改变了函数的链接属性。普通方法是有外部链接属性,由static修饰的函数外部链接属性变为内部链接属性。

    CalculateUtil.c

    #define _CRT_SECURE_NO_WARNINGS 1
    int Add(int x, int y) {
    
    	return x + y;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Main_exec.c

    #define _CRT_SECURE_NO_WARNINGS 1
    #include
    #include
    extern int Add(int x, int y);//可以省略
    int main() {
     
        int num1 = 20;
        int num2 = 30;
        int num3 = Add(num1, num2);
        printf("%d\n", num3);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    程序输出结果

    50
    
    • 1

    给Add函数添加static关键字
    CalculateUtil.c

    #define _CRT_SECURE_NO_WARNINGS 1
    static int Add(int x, int y) {
    
    	return x + y;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    程序分析

    执行Main_exec.c后会发现报错```LNK2019 | 无法解析的外部符号 Add,函数 main 中引用了该符号。
    得出结论:static修饰函数改变了函数的链接属性。普通方法是有外部链接属性,由static修饰的函数外部链接属性变为内部链接属性。

    #define 定义常量和宏

    #define定义标识符常量

    Main_exec.c

    #define _CRT_SECURE_NO_WARNINGS 1
    #include
    #include
    #define MAX 100;
    int main() {
     
        int num1 = MAX;
        printf("%d\n", num1);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    #define定义宏—带参数
    #define _CRT_SECURE_NO_WARNINGS 1
    #include
    #include
    
    #define MAX(x,y )(x > y ? x : y);
    
    int max(int x, int y) {
        return x > y ? x : y;
    }
    int main() {
     
        int num1 = 10;
        int num2 = 20;
        int num3 = max(num1, num2);//普通函数
        int num4 = MAX(num1, num2);//宏的方式
        printf("%d\n", num3);
        printf("%d\n", num4);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    指针

    用来存放地址的变量—指针

    内存

    内存是计算机上特别重要的存储器,计算机中所有程序的运行都是再内存中进行的。
    所以为了有效的使用内存,就把内存划分为一个个小的内存单元,每个内存单元的大小是1个字节
    为了能够有效的访问到内存的每个单元,就给内存单元进行编号,这些编号被称为该内存单位的地址
    1byte = 8bit

    如何产生地址

    32位: 32根地址线/数据线;正电(1)和负电(0)的区分。

    int a = 10;//4个字节
    int* p = &a;//取地址
    printf("%p\n",&a);//打印地址
    int c = *p;//*-解引用操作符,*p:找到*p所指向的对象
    printf("%d\n", c);
    *p = 20;
    printf("%d\n", a);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    程序输出结果:

    000000D3224FF954
    10
    20
    
    • 1
    • 2
    • 3

    指针变量的大小

    printf("%d\n", sizeof(char *));
    printf("%d\n", sizeof(short *));
    printf("%d\n", sizeof(int *));
    printf("%d\n", sizeof(double *));
    
    • 1
    • 2
    • 3
    • 4

    结论: 指针大小在32位平台是4个字节,64位平台是8个字节。

    32bit = 4byte;

    结构体

    结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。

    #define _CRT_SECURE_NO_WARNINGS 1
    #include
    #include
    
    //创建结构体类型
    struct Book {
        char name[20];
        char type[20];
        double price;
        double discount;
        double actualPrice;
    };
    int main() {
        //利用结构体类型创建一个该类型的结构体变量出来
        struct Book book1 = { "《重构》","架构",99.8,0.88,0.0};
        struct Book* bookAddr = &book1;
    
        printf("书名:%s\n",book1.name);
        printf("书类型:%s\n",book1.type);
        printf("价格:%lf\n",book1.price);
        //计算实际价格
        book1.actualPrice = book1.price * book1.discount;
        printf("实际价格为:%lf\n", book1.actualPrice);
        printf("书修改前的类型:%s\n", book1.type);
        strcpy(book1.type , "计算机/软件工程");//给book1.type赋值
        printf("书修改后的类型:%s\n", (*bookAddr).type);//type本质上是个地址
        printf("书修改后的类型:%s\n", bookAddr->type);
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    程序输出结果:

    书名:《重构》
    书类型:架构
    价格:99.800000
    实际价格为:87.824000
    书修改前的类型:架构
    书修改后的类型:计算机/软件工程
    书修改后的类型:计算机/软件工程
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    程序分析:

    直接使用book1.type = "计算机/软件工程";是不行的,因为type的类型是数组,无法直接进行赋值,需要使用strcpy(book1.type , "计算机/软件工程");即可;

  • 相关阅读:
    在线标注数据集Make Sense
    【C语言】函数的系统化精讲(二)
    红细胞膜包覆葫芦素B纳米结构脂质载体RBC-CuB-NLC /红细胞膜脂三尖杉酯碱脂质体
    【约束布局】ConstraintLayout配合Guideline解决两个子控件其中一个被挤出屏幕的问题
    node版本问题
    Ubuntu18.04版本下配置ORB-SLAM3和数据集测试方法
    XSS-labs靶场实战(一)——第1-3关
    【知网研学】使用方法
    作业 练习题
    [二进制学习笔记]Ubuntu20.04安装pip2&pip3
  • 原文地址:https://blog.csdn.net/Dreamlate_Spider/article/details/126772581