• C语言知识总结


    * 各个类型的变量输出的方式:

    double float 用 %f ,char 用 %c(打印字符) 和 %d(打印编码),int 用 %d,字符串用 %s,指针用 %p 打印

    * 定义变量不初始化,直接使用,并不会报错,结果输出这个变量是随机的。

    * 定义数组不初始化,分两种情况,有加 { } ,输出的值初始化默认是 0 ,而不是随机的;没加 { } ,则是随机的:

    a[3] = {1,2,3} //完全初始化

    a[3] = {};        //不完全初始化

    a[3] = {1};      //不完全初始化

    a[3];              //无初始化

    a[3] = {[0] = 1,[2] = 100};    //gcc 特有的初始化 ,指定位置数据

    a[3] = {1,[2] = 100};    //gcc 特有的初始化 ,指定位置数据

    这样定义数组,输出为:

    0 0 0

    1 0 0

    随机 随机 随机 

    1 0 100

    1 0 100

    ============================================================================

    指针:

    (1)

    int a = 11;   //定义 int 类型变量为 a

    int *p ;    //定义一个“指针类型”变量为 p,指向 int 类型数据(指针本身是一种类型)【可以写成:int * p 、int* p 都可以】

    p = &a;     // & 表示内存地址,这里表示把 a 的内存地址赋值给指针 p

    *p = 22;    //给指针类型p 赋值为 22 

    输出 a 等于:

    22      //最终就相当于修改了a的内存地址的值为 22

    (2)

    int a[5] = {55,44,33,22,11};

    int *p;

    ----

    p = &a;  //编译警告,但执行结果正确,打印 55【数组类型不能直接赋值给int类型的指针】

    p = &a[0];   //编译正常,执行正常,打印 55【这样表示“数据首元素”的首地址,意思和下面不同,但是值一样】

    p = a;    //编译正常,执行正常,打印 55【对于数组来说,直接使用变量 a,表示的是“整个数组的首地址”,和上面意思不一样,但是打印值一样】

    ----

    数组的两种表示方式,利用指针也可以来表示数组:

    例如有:

    int a[5] = {55,44,33,22,11};

    int *p;

    p = a;

    依次输出:

    第一种:a[0]  a[1]  a[2]  a[3]  a[4]

    第二种:*p  *(p+1)  *(p+2)  *(p+3)  *(p+4)

    void main() {
    	printf("===========\n");
    	int a[5] = {11,22,33,44,55};
    	int *p;
    	p = a;
    	
    	for(int i=0;i<5;i++){
    		printf("*p = %d \n",*(p+i));
    	}
    	printf("===========");
    }
    打印出:
    ===========
    *p = 11
    *p = 22
    *p = 33
    *p = 44
    *p = 55
    ===========
    

    指针在子函数中的使用:

    #include <stdio.h>
    
    int exchange1(int a,int b);
    int exchange2(int *a,int *b);
    
    void main() {
    	printf("===========\n");
    	
    	int x = 3,y = 5;
    	printf("begin param x = %d,y=%d\n",x,y);
    	
    	//exchange1(x,y);
    	exchange2(&x,&y);
    	
    	printf("begin param x = %d,y=%d\n",x,y);
    	
    	printf("===========");
    }
    
    int exchange1(int a,int b){
    	int t;
    	t = a;
    	a = b;
    	b = t;
    	return 0;
    }
    
    
    int exchange2(int *a,int *b){
    	int t;
    	t = *a;
    	*a = *b;
    	*b = t;
    	return 0;
    }
    
    //调用 exchange1 输出:
    ===========
    begin param x = 3,y=5
    begin param x = 3,y=5
    ===========
    //调用 exchange2 输出:
    ===========
    begin param x = 3,y=5
    begin param x = 5,y=3
    ===========
    

    结构体:(就类似 java 的对象)

    #include <stdio.h>
    
    //定义一个结构体,struct 是关键字
    struct User{
    	char name[20];	//姓名
    	int num;		//编号
    	int sex;		//性别
    };
    
    
    void main(void) {
    	printf("===========\n");
    	
    	struct User s;
    	s.name[0] = 'M';
    	s.name[1] = 'o';
    	s.name[2] = 'n';
    	s.name[3] = 'g';
    	s.name[4] = 'o';
    	
    	s.num = 38;
    	s.sex = 1;
    	
    	//字符输出用 %s
    	printf("name = %s,num = %d,sex = %d\n",s.name,s.num,s.sex);
    	
    	printf("===========");
    	
    }
    输出:
    ===========
    name = Mongo,num = 38,sex = 1
    ===========
    

    结构体初始化两种方式:

    方式一:struct User u = {x1,x2,x3,x4,x5};
    
    方式二:struct User u = {
    
      .a = x1,  //用逗号隔开,a前面的点不可省略
    
      .b = x2,
    
      .c = x3,
    
      .d = x4,
    
      .e = x5
    
    };  //最后的分号不可省略
    

    * 共生体(类似 java 的父类)

    ============================================================================

    * 宏定义 ://类似 java 的全局常量,命名全大写,下划线连接

    #define NUM (10)    //数据要用括号包起来

    #define SUM_NUM (NUM+10)     //后定义的可以使用上面先定义的,结合使用

    //例子,使用宏定义表示一年的秒数

    #define YEAR_SECOND (365*24*60*60)UL    //UL 表示强制赋值,不然默认为 int 类型,超出长度了,也可以简写成 U【UL 表示无符号类型】

    ============================================================================

    * 枚举

    enum week{

      SUN,

      MON,

      TUE,

      WEN,

      THU,

      FRI,

      SAT

    }

    ============================================================================

    * void 用法,类似 java 里面的 Object 类型,可以接纳所有类型

    void main(void) {
    	printf("===========\n");
    	
    	int a = 123;
    	void *p;	//定义 void 类型的指针
    	p = &a;
    	printf("*p = %d\n",*(int *)p);		//正确
    	printf("*p = %f\n",*(float *)p);	//错误
    	
    	printf("===========");
    	
    }
    

    * C语言没有 bool 类型(C++ 有),需要使用的时候,用  int 代替,在C语言中,除了 0 ,其余正负 int 数据,都是 1 

    * 全局变量和局部变量

      只是定义没有初始化的情况下,局部变量每次数据是“随机值”,全局变量默认是 0

    静态局部变量和全局变量很像,可以累加使用,唯一的不同就是静态局部变量还是局部方法里面使用,全局是整个程序使用。

    #include <stdio.h>
    
    void fun1();
    void fun2();
    
    void main(void) {
    	printf("===========\n");
    	fun1();
    	fun1();
    	fun1();
    	
    	printf("-----------\n");
    	
    	fun2();
    	fun2();
    	fun2();	
    	printf("============");
    	
    }
    
    void fun1(){
    	int a = 1;
    	a++;
    	printf("a = %d\n",a);
    }
    
    void fun2(){
    	static int b = 1;	//静态局部变量,只初始化一次,后续不再初始化
    	b++;
    	printf("b = %d\n",b);
    }
    输出:
    ===========
    a = 2
    a = 2
    a = 2
    -----------
    b = 2
    b = 3
    b = 4
    ============
    

    * 多文件的相互调用:

    比如:a.c 和 b.c 有两个文件,在编译的时候,使用命令:gcc a.c b.c -o ab 即可把两个文件关联成一个项目。

    如果两者之前的函数,变量要相互调用,必须在顶部声明:

    (1)对于函数,和单独一个文件的声明方式一样,直接声明即可。【两个文件不能出现一样的函数名字】

    (2)对于变量(只有全局变量),有两种方式来使用,

        ①间接使用,比如 a.c 文件中一个函数 fun 调用了,在 b.c 文件中调用函数 fun 即可间接使用该变量

        ②使用关键字:extern 来声明,比如:

    a.c 文件中有一个全局变量 :int g_a = 11;

    b.c 文件中要使用,则这样声明:extern int g_a; //不可再赋值

    * 静态全局变量的理解:

    普通全局变量,是整个项目都可以使用的,一旦定义,即使不同文件之前也不能再出现重名的;

    静态全局变量,就是规定只在我当前这个文件中可以使用,另外的文件不可以使用。

    * 常量(不会改变的值)

    方式:

    ①宏定义就是一种常量的表现形式

    ②使用关键字:const 定义。例如:const int a = 1;

    “常量”和“指针”结合的重点理解:

    const int *p;      //p是一个指针,指针指向一个int类型的数据。p所指向的是一个常量

    int const *p;      //p是一个指针,指针指向一个int类型的数据。p所指向的是一个常量

    int *const p;      //p是一个指针,指针指向一个int类型的数据。p本身是常量,p所指向的是一个变量

    const int *const p;  //p是一个指针,指针指向一个int类型的数据。p本身是常量,p所指向的也是一个常量

     * 回调函数:把整个函数当作参数传给另一个函数使用,需要用到指针来配合。

    使用场景:当 A 函数的执行时间需要由 B 函数来决定时,可以把 A 函数当作参数,整个传给 B 函数,然后由 B 来执行。

     返回函数指针:

    注意: typedef int (*opFunc)(int,int)  中 typedef 后面的 int 类型,取决于 add 和 sub 函数的返回类型!

     函数指针数组:

     * 堆的动态申请和释放

    * 越界:

  • 相关阅读:
    python_Memcached
    python_day10_IO多路复用
    java_list,set,map集合
    python3.0_day9_scoket基础之篇
    redis.conf配置文件详解
    Java_数组
    面向接口编程初识(转)
    SSH三种框架及表示层、业务层和持久层的理解(转)
    解决win10磁盘占用过大的问题(亲测有效)
    ORA-12541:TNS:无监听程序
  • 原文地址:https://www.cnblogs.com/xuehuashanghe/p/15888483.html
Copyright © 2020-2023  润新知