C语言学习笔记

C语言是一门高级语言,是一门结构化语言,是面向过程的。

下面的试验均基于Dev-C++

面向过程和面向对象的区别

  • 面向过程:分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一再依次调用,面向过程以步骤划分问题

  • 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。面向对象以功能划分问题

关于变量、常量要知道的

  • 变量本质上是内存中的一段存储空间

  • 定义一个变量,相当于请求操作系统将内存中某一块空间的使用权分配给该变量

  • 变量如果不初始化使用,将会保留原来该区域中遗留的“垃圾数据”

  • 常量以二进制代码存储在计算机中

    • 整数以补码形式转换为二进制代码存储在计算机中
    • 实数以IEEE754标准转换为二进制代码存储在计算机中,值得注意的是计算机无法精确的存储浮点数
    #incude<stdio.h>
    int main()
    {
        float i = 99.9;
        printf("%f",i);
        return 0;
    }
    
    

    image-20200524155948356

  • 字符本质上与整数的存方式相同(ASCII)

scanf和printf的基本用法

——Note:C语言中“;”作为一个语句的结束标志
#include<stdio.h>
int main()
{
    
    int i;//定义一个变量
//printf可以直接输出字符串
    printf("请输入一个数:");
//scanf是C语言中与用户交互的函数,会等待用户输入,具体用法:
    scanf("%d",&i);
/*
    “”号中的%d是输出控制符指以十进制类型输入
    &是取地址符,意为将输入的值赋给上面定义的变量i
    “”中不要加其他字符,否则输入时,要原样输入
*/
    
//printf也可以格式化输出
    printf("这里将原样输出----%d",i);//以十进制方式输出i
  	return 0; 
}

image-20200524160833192

输入输出控制符
控制符类型
%dint
%ldlong int
%cchar
%ffloat
%lfdouble
%x或%X或%#x或#X16进制输出
%o8进制输出
%s字符串

test

#include<stdio.h>
int main(void){
	int i = 46;
	
	printf("%x\n",i) ;
	printf("%X\n",i) ;
	printf("%#x\n",i) ;
	printf("%#X\n",i) ;//?
    
    int j = 10;
    printf("%o\n",j);
    
    char str[4] = "ABC";
    printf("%s\n",str);
	
	return 0;
} 

image-20200524162346549

&&和|| 的短路运算

为了提升效率

  • &&左边为假,右边的表达是不会执行

  • ||左边为真,右边的表达式不会执行

除法和取模运算符

  • 除法/的运算结果和运算对象的类型有关,int/int的结果还是int,换句话说,小数部分被舍弃

  • 要想保留小数部分,需要让除数或被除数为浮点型

    • #include<stdio.h>
      int main()
      {
      	int i = 5;
      	int j = 2;
      	float m = 2.0;
      	
      	float residi,residf,res;
      	residi = i/j;
      	residf = i/m;
      	res = i*1.0/j;//用这种方式可以简单的将转换为浮点	
      	printf("i/j = %f\ni/m = %f\n1.0*i/j = %f",residi,residf,res);
      	return 0;
      }
      

      image-20200526153347007

  • 取余%的运算对象必须是整数,结果是整除后的余数,其余数的符号和被除数相同

    • #include<stdio.h>
      int main()
      {
      	int i = 10;
      	int j = -10;
      	int m = 3;
      	printf("i%%m = %d\nj%%m = %d",i%m,j%m);//因为%是一个特殊的字符,所以写两个%才能输出一个% 
      }
      

      image-20200526154026411

流程控制

——任何复杂的算法,都可以由顺序结构、选择(分支)结构和循环结构三种基本结构组成

  • 顺序:程序中的各个操作是按照它们在源代码中的排列顺序依次执行的;

  • 选择:根据条件,选择一些代码执行,另外的代码不执行

#include<stdio.h>
int main(void){
	float s;
	printf("请输入分数:");
	scanf("%f",&s);
	if(s>=90)
		printf("%c",'A');
	else if(s >= 80)
		printf("%c",'B');
	else if(s >= 70)
		printf("%c",'C');
	else if(s >= 60)
		printf("%c",'D');
	else
		printf("%c",'E');	
	
	return 0;
} 


#include<stdio.h>
int main()
{
	float s;
	printf("请输入分数:");
	scanf("%f",&s);
	switch((int)(s/10))
	{
		case 10://这里没有break,就会一直执行到下一个break,这里要注意,之前有错过
		case 9:
			printf("%c",'A');
			break;//出口 
		case 8:
			printf("%c",'B');
			break;//出口 
		case 7:
			printf("%c",'C');
			break;//出口 
		case 6:
			printf("%c",'D');
			break;//出口 
		default:
			printf("%c",'E');
			break;//出口 	
	}
	 
	return 0;
}
/*
switch语句规则:
1、switch语句非常有用,但在使用时必须谨慎。所写的任何switch语句都必须遵循以下规则:
2、只能针对基本数据类型中的整型类型使用switch,这些类型包括int、char等。对于其他类型,则必须使用if语句。
3、switch()的参数类型不能为实型 。
4、case标签必须是常量表达式(constantExpression),如42或者'4'。
5、case标签必须是唯一性的表达式;也就是说,不允许两个case具有相同的值。
*/

循环

  • for循环

    • 单层循环:求1-100的和

      #include<stdio.h>
      int main()
      {
      	int sum = 0;
      	for(int i = 1;i<=100;i++)
      	{
      		sum += i;
      	}
      	printf("%d",sum);
      	return 0;
      }
      /*
      result:5050
      */
      
    • 嵌套循环:输出:

        *
       ***
      *****
      
      #include<stdio.h>
      int main()
      {
      	for(int i = 0;i < 3;i++)
      	{
      		if(i!=0)
      		{
      			printf("\n");
      		}
      		
      		for(int k = 0;k<3-1-i;k++)
      		{
      			printf(" ");
      		} 
      		
      		for(int j = 0;j<2*(i+1)-1;j++)
      		{
      			printf("*");
      		}
      	}
      	return 0;
      }
      
  • while循环

    • while循环和for循环可以互相转换

      1;
      while(2)
      {
      	A;
          3;
      }
      
      for(1;2;3)
      {
          A;
      }
      /*
      1一般只执行一次
      2成立执行A
      A执行后执行3
      3成执行后执行2
      2不成立循环结束
      */  
      
  • do while循环

/*
do while 和for、while不一样,他至少执行一次
*/
do{
	...
}while(表达式)

break和continue

  • break如果用于循环是用来终止循环,在多层循环中, break只能终止最里面包裹它的那个循环

  • break如果用于 switch,则是用于终止 switch

  • break不能直接用于if,除非if属于循环内部的一个子句

  • continue用于跳过本次循环余下的语句,转去判断是否需要执行下次循环

    while((ch = getchar())!='\n')
        continue;
    /*
    该语句为了屏蔽用户的某些非法输入
    比如在前面输入了111abd
    在执行了111还有残留的abd,可能对下一次的输入产生影响,该语句可屏蔽该影响
    */
    

静态数组和动态数组

——为了解决大量同类型数据的存储和使用问题

  • 静态数组

    /*
    一维数组
    为n个变量连续分配存储空间
    所有变量的数据类型必须相同
    所有变量所占字节大小必须相同
    数组名表示数组第一个元素的地址
    构建静态数组时,[]中不能写变量,也就是说不能通过用户输入的值来确定数组长度
    */
    int a[5];//声名数组,不初始化,所有元素都是垃圾值
    int a[5] = {1,2,3}//不完全初始化,其他变量是0
    int a[5] = {1,2,3,4,5};//声名并完全初始化
    int a[5] = {0};//清零
    
    /*
    二维数组
    int a[3][4];//可以看作3行4列
    */
    
    /*
    多维数组
    计算机的内存是线性一维的
    严格意义上不存在多维数组
    n维数组可以当做每个元素是n-1维数组的一维数组
    */
    
    
  • 动态数组

    #include<stdio.h>
    #include<malloc.h>
    int main()
    {
        int len;
    	int * pArr;
    	int i; 
        //静态构造一维数组
    	int a[20];//如果int占4个字节,则本数组共包含有20个字节,每四个字节当作一个int变量使用 
        
    	//动态的构造一维数组 
    	printf("请输入要存放元素的个数:");
    	scanf("%d",&len);
    	pArr = (int *)malloc( sizeof(int) * len); //等同 int pArr[len]  本行 动态的构造了一个一维数组 
    	for(i = 0;i<len;i++)
    	{
    		printf("请输入第%d个数:",i+1); 
    		scanf("%d",&pArr[i]);
    	}
    	
    	for(i = 0;i<len;i++)
    	{
    		printf("%d ",pArr[i]);
    	}
    	free(pArr);//释放动态数组 
    	return 0;
    } 
    /*
    pArr指向动态数组的第一个元素的地址
    *pArr 等同于pArr[0]
    因为连续
    所以*(pArr+i) 等价于 pArr[i]
    动态分配的一维数组使用方式与静态几乎类似
    */
    

函数

——为了避免重复性的操作,有利于程序的模块化

/*
函数的使用,输出1-100内的素数
*/
#include<stdio.h>
#include<math.h>

//定义判断素数的函数 
bool JudgePrime(int num)
{
	for(int i = 2;i<=sqrt(num);i++)
	{
		if(num%i==0)
		{
			return 0;
		}
	}
	return 1;
}

//给定一个整数,输出1-该整数中所有的素数
void Traverse(int N)
{
	for(int i = 2;i<N;i++)//1不是素数 
	{
		if(JudgePrime(i))
		{
			printf("%d ",i);
		}
	}
}
 
int main()
{
    /*
    将步骤写成函数,可以让主函数变得更加简洁,同时减少了不必要的重复性操作
    */
	int N;
	printf("请输入数字N,我来帮你求1-N的所有素数:");
	scanf("%d",&N);
	Traverse(N);
	return 0;
} 
//注意:如果函数调用写在了函数定义的前面,则必须加函数前置声明

指针

——指针可以用于表示一些复杂的数据结构(树、图)

——快速的传递数据,减少内存的耗用

——使函数放回一个以上的值

——能直接访问硬件

——能够方便的处理字符串(\0休止符的存在)

——理解面向对象语言中引用的基础

  • 指针就是地址,所谓地址是内存单元的编号,范围[0,内存大小(比如8G)-1]

  • 指针变量和指针不一样,指针变量是存放指针(地址)的变量,指针变量的占字节的大小与类型无关,与操作系统位数和编译器环境相关,32位4个字节,64位8个字节。

    • #include<stdio.h>
      int main()
      {
      	int * p;
      	double * k;
      	printf("int * 占的字节数:%d\ndouble * 占的字节数:%d",sizeof(p),sizeof(k));
          //sizeof函数用于返回变量占的字节数
          return 0;
      }
      
      • 在64位系统,64位编译环境下:

        image-20200526155902821

      • 在64位系统,32位编译环境下:

        image-20200526155951093

  • 指针的本质是一个操作受限的非负整数

基本类型指针

  • 基本用法和概念辨析
    • #include<stdio.h>
      #include<math.h>
      
      int main(void) 
      {
      	int * p;// 定义指针变量p,指针变量p存放的是----int类型----的----地址---现在p放的是垃圾值
      	int i = 5;//将5赋给系统分配的名称为i的内存空间
      	p = &i; //这里是第8行,将i的地址赋给指针变量i &是取地址符,能够获得变量的内存单元的编号
          *p = i;
          /*
          若第8行被注释掉,这里的写法是危险的,因为将i赋给了未经系统分配的内存空间
          若第8行没被注释,这里指将i赋给以p的内容为地址的变量即i
          */
      	 
      	/*
      	p保存了i的地址,所以p指向i
      	p和i不同,p相当于复制的i的地址,修改p的值不影响i的值,修改i的值不影响p的值
      	如果一个指针变量指向一个普通变量 则
      	*指针变量 与该普通变量等价 
      	eg:
      		如果p是个指针变量,并且p保存了普通变量i的地址,则
      		p指向了普通变量i
      		*p 完全等同于 i
      		或者说:
      		在所有出现*p的地方可以替换成i
      		同理
      		在所有出现i的地方可以替换成*p
      		*p中的*相当于取地址符的逆操作,换句话说就是以p的内容为地址的变量 
      		
      		指针VS指针变量
      		指针:地址【内存单元中具体的(编号)值】 
      		指针变量 :存放指针的变量 
      		 
      	*/ 
      	printf("%d",*p);//若第八行没有被注释,这里将输出5
      	return 0;
      }
      
  • 通过被调函数修改主调函数的值
    • #include<stdio.h>
      
      //通过获取主调函数中变量的地址,来改变主调函数中该变量的值 
      void changeIOut(int * p)//形参为指针变量,接受主调函数中传来的变量的地址 
      {
      	*p = 100;//通过* ,将100赋给以p的内容(&I)为地址的变量(I) 
       } 
       
      int main()
      {	
      	int I = 10;
      	printf("I before:%d\n",I);
      	changeIOut(&I);
      	printf("I after:%d",I);
      	return 0;
      }
      

      image-20200526162912494

指针和数组

  • 指针和一维数组

    • 一维数组名是个指针变量
    • 它存放的是一维数组第一个元素的地址
  • 数组下标和指针的关系

  • 如果p为指针变量,则p[i]等价于*(p+i)

  • 确定一个一维数组需要两个参数

    • 数组第一个元素的地址
    • 数组的长度
    #include<stdio.h>
     
    int main()
    {	
    	int a[5] = {1,2,3,4,5};//定义一个数组,并初始化
    	int * p = a;//将a赋给p,如果a是地址的话,这里才不会报错,相同类型的变量才能互相赋值 
    	//如果,上面没有问题,这里验证*(p+i)与a[i]是否等价 
    	for(int i = 0;i<5;i++)
    	{
    		printf("a[%d]:%d\n",i,a[i]);
    		printf("*(p+%d):%d\n",i,*(p+i));
    		printf("-----------\n");//无意义,为了看的清楚点 
    	 } 
    	return 0; 
    }
    

    image-20200526170207473

变量的地址

  • 一个变量的地址,是用该变量的首地址来表示的,那么如何保证变量的完整?
  • 变量类型划分了从首地址开始,以该变量类型所占字节为长度的变量,这就是为什么定义变量时一定要给出类型的原因

指针与函数

#include<stdio.h>

/*
以下函数不能完成互换功能
R:虽然都叫变量a,和变量b
但是函数里的a,b与主函数的不同 
形参和实参是不一样的!!!!!!!
*/ 
void SwitchAB_1(int a,int b)
{
	int t;
	
	t = a;
	a = b;
	b = t;
	
	return;	
} 

/* 
以下函数不能完成互换功能
只是互换p,q的内容,对a,b没有影响
要根据p,q的 内容,找到它们对对应的变量,并互换变量内的值 
*/ 
void SwitchAB_2(int * p,int * q)
{
	int * t;
 
	t = p;
	p = q;
	q = t;
	
	return;	
} 


//可以完成互换 
void SwitchAB_3(int * p,int * q)
{
	int t;
 
	t = *p;
	*p = *q;
	*q = t;
	
	return;	
} 

//可以完成互换 
void SwitchAB_4(int &a,int &b)  
{
	int t;
	t = a;
	a = b;
	b = t;
	return;	
} 

int main(void)
{
	int a=5,b=6;
	int t;
    //下面3行是主调函数内完成的互换
	t=a;
	a=b;
	b=t;
	printf("正常的互换:a:%d  b:%d\n",a,b);//a:6 b:5
	
	SwitchAB_1(a,b);
	printf("later1 a:%d  b:%d\n",a,b);//a:6 b:5 失败
	
	SwitchAB_2(&a,&b);//SwitchAB_2(a,b)是错误的 
    printf("later2 a:%d  b:%d\n",a,b);//a:6 b:5 失败
    
    SwitchAB_3(&a,&b);
    printf("later3 a:%d  b:%d\n",a,b);//a:5 b:6 成功
    
    SwitchAB_4(a,b);
    printf("later4 a:%d  b:%d\n",a,b);//a:6 b:5 成功
	return 0;
 } 
 
 int test(int * p, int * q){
 	int  t;
 	t = *p;
 	*p = *q;
 	*q = t;
 	return;
 }

image-20200526172052247

指针变量的运算

  • 指针变量的加法,乘法,除法没有意义

  • 如果两个指针变量指向的是同一块连续空间中的不同存储单元,那么它们相减意味着隔了”多远“

  • 注意:

    • 指 针 相 减 = ( 地 址 1 − 地 址 2 ) / s i z e o f ( 类 型 ) 指针相减=(地址1-地址2)/sizeof(类型) =(12)/sizeof()

多级指针

#include<stdio.h>
 
int main()
{	
	int i = 6;
	int * p = &i;//p只能存放int类型变量的地址 
	int ** q = &p;//q只能存放int * 类型变量的地址 那么*q == p **q == i 地址的地址 
	int *** r = &q;//r只能存放int ** 类型变量的地址 地址的地址的地址 //禁止套娃 ε(┬┬﹏┬┬)3 
	printf("***r:%d **q:%d *p:%d",***r , **q, *p); 
	return 0; 
}

静态和动态分配内存

  • 静态数组的缺点
    • 长度必须事先制定,只能是产量不能为变量
    • 静态数组的内存不能由程序员手动释放,必须要等包含该数组的函数运行完毕,系统才会自动释放
    • 数组的长度不能在函数运行过程中扩充或缩减
    • 由于静态变量、数组存在在栈中,也就意味着,不可能跨函数调用
  • 动态分配内存为了解决上述缺点
    • malloc函数的用法

      #include<stdio.h>
      #include<malloc.h>
      /*
      malloc (memory allocate 内存分配)函数的用法 
      int * p = (int *)malloc(int len); //事实上 ,int len为保证安全,更常写为:sizeof(int)*len
      malloc 函数的功能是请求系统分配len个字节的内存空间,
      成功则返回第一个字节的地址,失败则返回NULL
      由于为了保证变量的完整性,需要强制类型转换,前面加(int *),以具体划分
      
      比如 double * p = (double *)malloc(80);
      这里向系统请求分配80个字节的内存空间,并将第一个字节的地址返回给p,
      同时又指定了double * 类型,系统就知道从第一个地址开始后续的8个字节作为一个整体
      即p 指向了第一个 8个字节,p+1指向了第二个 8个字节...
      */
      int main(){
      	
      	int 5;//静态分配了5个字节
      	int * p = (int *)malloc(4);//这里共分配了8(p本身 64位环境)+4 = 12个字节 
      		/*
      			1.要使用malloc函数,必须添加malloc.h头文件
      			2.malloc只有一个形参,并且形参为整形
      			3.4表示请求系统为该函数分配4个字节
      			4.malloc函数只能返回第一个字节得地址
      			5.所以要通过指定类型来指定第一个字节得地址是什么类型的地址 
      	6.p本身所占得内存是静态分配得,而p指向的内存是动态分配的 
      		*/ 
      	*p = 5;	
      	//动态分配的可以手动释放
      	free(p);//表示把p指向的内存给释放掉 p本身的内存是静态的,不能由程序员释放,只能在函数执行完后,自动释放  
      		
      	return 0;
      } 
      
  • 动态内存和静态内存的对比
    • 静态变量不能跨函数使用内存

      #include<stdio.h>
      
      void f(int ** q)//q是个指针变量,无论是 什么类型的指针变量,都只占8个字节(64 位环境) 
      {
      	int i = 5;//静态变量不能跨函数使用,因为它们存储在栈中,出栈意味着,资源被释放,也就没有读写权限 
      	//*q等价于p 
      	*q = &i;//p = &i;
      	
      }
      int main()
      {
      	int * p;
      	f(&p);
      	printf("%d\n",*p);//这里逻辑上存在问题,i在f函数执行完后就已经释放了,*p访问了一个没有权限的变量	 
      	return 0;
      } 
      
    • 动态变量跨函数使用内存

      #include<stdio.h>
      #include<malloc.h>
      void f(int ** q)
      {
      	*q = (int *)malloc(sizeof(int)*1);//动态分配的变量在堆内,函数执行后,不会被释放 
      	**q = 5;
      }
      
      int main()
      {
      	int * p;
      	f(&p);
      	printf("%d\n",*p);	//输出为5
      	return 0;
      }
      
    • 总结

      • 静态内存是由系统自动分配,由系统自动释放,是在分配的
      • 动态内存是由程序员手动分配,可手动释放,是在分配的
      • 静态内存不能跨函数使用,是因为,静态内存在栈中分配,一旦该函数出栈,意味着函数中的静态内存将被释放,该内存空间的权限被收回,在另一个函数中调用系统未分配的空间是危险的
      • 动态内存则可以跨函数使用,因为它分配在堆中,即便函数出栈,也不影响它。

结构体

——为了表示基本数据类型无法表示的事物,比如学生,他可以有姓名,性别,分数等,需要多个变量综合起来才能描述的事物

——结构体,是一些基本类型数据组合起来形成的新的复合数据类型

  • 结构体定义,基本用法
    #include<stdio.h>
    
    //define 结构体的第一种方式 推荐 仅仅定义了一个新的数据类型,并没有实例化 
    struct Student
    {
    	int age;
    	float score;
    	char sex;	
    };
    
    //define 2
    struct Student2
    {
    	int age;
    	float score;
    	char sex;	
    }st2 ;
    
    //define 3
    struct
    {
    	int age;
    	float score;
    	char sex;	
    }st3;
     
    int main()
    {
    	struct Student st1 = {80,66.6,'F'};//结构体的赋值和初始化(定义的同时赋初值)
    	struct Student st2 ;
    	
    	//结构体访问成员变量 1  结构体变量名.成员名 
    	st2.age = 66;
    	st2.score= 90;
    	st2.sex = 'M';
    	printf("%d %f %c\n",st1.age,st1.score,st1.sex);
    	printf("%d %f %c\n",st2.age,st2.score,st2.sex);
    	//结构体访问 2  指针变量名->成员名 用的多 
    	struct Student * pst = &st1;//因为st1 是Student类型则,指向它的指针也是该类型
    	pst->score = 66.7f;//pst->age在计算机内部会被转换成(*pst).age  pst->age = st.age 66.7在C语言中默认是double类型 
    	printf("%f ",st1.score) ;
    	//pst->age 含义:pst所指向的那个结构体变量中的age成员 
        
    	return 0;
     } 
    
  • 一个例子(综合性)
    #include<stdio.h>
    #include<malloc.h>
    
    //定义Student结构体,由age,score,name 属性
    struct Student
    {
    	int age;
    	float score;
    	char name[100];	
    };
    //输入学生信息
    void InStInfo(struct Student * p,int i)
    {
    	printf("请输入第%d个学生的信息:\n",i+1);
    	printf("age : ") ;
    	scanf("%d",&p[i].age);
    	printf("name : ") ;
    	scanf("%s",p[i].name);//name 本身是数组名,所以在scanf 函数里不需要加取地址符 
    	printf("score : ") ;
    	scanf("%f",&p[i].score);
    }
    
    //输出学生信息 
    void OutStInfo(struct Student * p,int i)
    {
    
    	printf("第%d个学生的信息:\n",i+1);	
    	printf("age : %d\n",p[i].age) ;
    	printf("name : %s\n",p[i].name) ;
    	printf("score : %f\n",p[i].score) ;
    	printf("\n");
    }
    
    //通过冒泡排序按学生升序排 
    void sortUp(struct Student * p,int * len)
    {
    	for(int i = 0;i<*len;i++)
    	{
    		for(int j = 0;j<*len-1-i;j++)
    		{
    			if(p[j].score>p[j+1].score)//根据学生成绩高低,给学生整体排序,而不是单纯的换成绩本身,那没有意义
    			{
    				struct Student t;//换的是学生,所以变量类型是struct Student类型
    				t = p[j];
    				p[j] = p[j+1];
    				p[j+1] = t;
    			}
    		}
    	}
     } 
     
    int main()
    {
    	int len; 
    	struct Student * pArr;
    	
    	printf("请输入学生的个数:\n");
    	printf("len = ");
    	scanf("%d",&len);
    	
    	pArr = (Student *)malloc( len * sizeof(Student) );
    	for(int i = 0;i < len;i++)
    	{
    		InStInfo(pArr,i);
    	}
    	//排序
    	sortUp(pArr,&len); 
    	//输出
    	printf("\n\n学生的信息如下:\n\n");
    	for(int i = 0;i<len;i++)
    	{
    		OutStInfo(pArr,i);
    	 } 
    	return 0;	
    } 
    

枚举

——把所有事物的取值意一一列举出来

  • 枚举的基本用法
    #include<stdio.h>
    //定义了一个数据类型,并没有定义变量 
    enum WeekDay
    {
    	MonDay,TuesDay,WednesDay,ThursDay,FriDay,SaturDay,SunDay//从0开始
    };
    int main()
    {
    	enum WeekDay day = WednesDay;
    	printf("%d\n",day);//这里输出为2
    	return 0;
     } 
    

    image-20200527155448576

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值