C语言(下)

五、数组

一维数组

1、定义

​ 【存储类型】 数据类型 标识符 【下标】

​ 特点:在内存中连续存放

​ 理解:就是一个变量,连续存放

2、初始化

​ 不初始化
​ 全部初始化
​ 部分初始化
​ static

3、元素引用

​ 数组名 【下标】

4、数组名

​ 数组名是表示地址的常量

5、数组越界

​ 数组越界不检查

经典🌰
fibonacci斐波那契数列:第n项等于前两项之和(n>2)
//求fibonacci数列的前n项,并在数组中逆序排列

static void fibonacci(void)
{
    int i;
    int j,tmp;
    int fib[N] = {1,1};

    for(i = 2; i < N ;i ++)      //求出每一项,每一项等于前两项之和 ,并打印
        fib[i] = fib[i-1] + fib[i-2];
    for(i = 0; i < N ;i ++)
        printf("%d ",fib[i]);
    
    printf("\n");
}

冒泡排序:从第一位开始,第一位和第二位比较,大则交换,然后第二位和第三位比较,大则交换,依次相邻两位进行比较,一次之后最后一位数值最大;
重复上述步骤,进行N-1次比较后实现从小到大排序 。 每次只判断一个数,比大小,朝前或朝后移动(小数慢慢浮起来,大数沉下去慢慢)

#include<stdio.h>
#include<stdlib.h>
#define N 10
static void sort1(void)
{
    int i,j,tmp;
    int a[N]={45,48,24,46,68,48,24,33,1,2};
    for(i=0;i<N;i++)
            printf("%d ",a[i]);
    printf("\n");
 
    for(i=0;i<(N);i++)      //冒泡排序关键步骤
    {
        for(j=0;j<(N-i);j++)
        {
            if(a[j]>a[j+1])
            {
                tmp=a[j];
                a[j]=a[j+1];
                a[j+1]=tmp;
            }
         }
    }
    
    for (i=0;i<N;i++)   //输出
         printf("%d ",a[i]);
    printf("\n");
}

int main()
{
    sort1();
}

选择法排序:将第一位与后面所有数值比较,比第一位小则交换位置; 第一位不动,第二位与后面其他值比较,比第二位小则交换位置以此类推,进行N-1次排序,实现N个数从小到大排序

static void sort2(void)  
{
    int a[N] = {23,45,90,76,13,55,76,45,3,8};
    int i,j,k,tmp;

    for(i = 0; i < sizeof(a)/sizeof(a[i]) ; i++)
        printf("%d ",a[i]);
    printf("\n");

    for(i = 0 ; i < N-1 ; i++)  //外循环,控制每一趟,共N-1趟
    {
        k=i;
        for(j = i+1; j < N ; j++)  //内循环,控制每一趟中的第几位进行比较
        {
            if(a[j] < a[k])
                k = j;
        }
        if(i != k)
        {
            tmp = a[i];
            a[i] = a[k];
            a[k] = tmp;
        }
    }

    for(i = 0; i < sizeof(a)/sizeof(a[i]) ; i++)
        printf("%d ",a[i]);
    printf("\n");
}

二维数组

定义:【存储类型】 数据类型 标识符 【行下标】 【列下标】
数组名即为数组起始位置

🌰:int M[2] [3] 两行三列的数组 

在存储空间按行存放如:M[0] [1] M[0] [2] M[1] [0] M[ ] [1] M[0] [1]
部分数组初始化:int a[3] [3]={{1,2}{5,6}}
全部数组初始化:int a[3] [3]={{1,2,3},{4,5,6},{7,8,9}}
定义可以行省略:例如:int a[][N]={4,8,45,65,8}

存储形式:在一块空间连续存储


深入理解二维数组

​ 二维数组,本质上是多个一维数组组成的
​ 主要是理解行指针和列指针

字符数组

1、定义 , 初始化 ,存储特点

​ 【存储类型】 数据类型 标识符 【下标】
​ 单个字符初始化
​ 用字符串常量初始化

2、输入输出
scanf("%s",str);
printf("%s",str);

注意%s无法获得带分隔符的字符串

🌰
输入 hello word
输出为 hello

输入可以改为 scanf(“%s%s”,str) 来解决这个问题;

3、常用函数

因为int等类型可以用if来比大小,也可以相互赋值,但是字符串的名字就是一个地址常量,没办法比较大小,赋值等操作,所以需要常用函数来解决这些问题
不能直接复制 例如: str=“abcde”,这个是不成立的

(1)strlen
	作用:以尾零作为结束,显示当前字符串个数 (输入Hello word,返回值为5printf("%d\n",strlen(str))
(2)sizeof
	作用:该字符串在内存所占字节个数 (输入Hello word,返回值为11printf("%d\n",sizeof(str));
(3)strcpy
	用法strcpy(str,"abcde"); 作用:将abcde字符串copy到str中
	puts(str);	
(4)strncpy
	用法:strncpy(str,“abcde”,STRSIZE); 
	作用:将abcde字符串copy到str中,但是STRSIZE会限制copy个数,防止溢出
(5)stract
 	char *strcat(char *dest, const char *src);
 	作用:将两个字符串首尾连接
(6)strncmp
	int strcmp(const char *s1, const char *s2);
	作用:比较ASCLL码大小,根据比较大小情况,返回值为1,0,-1

经典代码

//编写一个字符串拷贝

#include <stdio.h>
#include <stdlib.h>

char *mystrcpy(char *dest,const char *src)
{
    char *ret = dest;
    if(dest != NULL && src != NULL)
        while((*dest++ = *src++) != '\0')
    return ret;
}


char *mystrncpy(char *dest, const char *src, size_t n)
{
    int i;

    for(i = 0; i < n && (dest[i] = src[i]) ;i++);
        ;
    dest[i] = '\0';
    
    return dest;
}

int main()
{
    char str1[] = "helloworld";
    char str2[128];

    mystrcpy(str2,str1);
    //mystrncpy(str2,str1,5);
 
    puts(str2);

    exit(0);
}
`

]) ;i++);
        ;
    dest[i] = '\0';
    
    return dest;
}

int main()
{
    char str1[] = "helloworld";
    char str2[128];

    mystrcpy(str2,str1);
    //mystrncpy(str2,str1,5);
 
    puts(str2);

    exit(0);
}

六、指针

1、变量与地址

​ 变量: 抽象出来的某一块空间的命名,能变,就是能读能写,必定在内存里
​ 地址: 即指针,即指针保存的是地址
在这里插入图片描述

🌰
int i = 1;
int *p = &i;
int **q = *p;
---> 
     i = 1
    &i = 0x2000
    
     p = 0x2000 = &i             --> p = &i;
    &p = 0x3000
    *p = *(0x2000) = *(&i) = i   --> *p = i;
    
     q = 0x3000 = &p
    &q = 0x4000 
    *q = *(0x3000) = *(&p) = p   --> *q = p = &i;
    **q = *p = *(&i) = i         --> **q = i
 理解上述i, *p, **p 之间的关系,指针就没多大问题了
 访问 i 的值:可以通过 i, *p, **q
 访问 i 的地址:可以通过 &i, p, *q

2、指针与指针变量

*定义:[数据类型] p=&i;

🌰  
int *p = &i ;相当于:定义一个指针类型的p,然后把i的地址 赋给p;
	int *p;
	 p = &i;
i 的值等价于:  i , *p, **q
i 的地址等价于:&i , p , *q

​ 指针:
​ 指针变量
​ 无论是什么类型的指针,在64位处理器中所占字节数 sizeof§ ,所占字节均为8

🌰                                                                                                                  
   int *p;
   char *p;
   doubule *p;;
   struct ×× *p; //结构体指针

无论是什么类型的指针,sizeof(*p) 在64位所占字节数 均为8
虽然指针所占字节,指针变量和他所指类型的值,一定要相符

🌰
#include <stdio.h>                                                                                                           
#include<stdlib.h>
int main()
{
    int i=1;
    int *p;
    p=&i;
    printf("i=%d\n",i); 	//输出i的值
    printf("&i=%p\n",&i);	//i的地址
    printf("p=%p\n",p );	//p的值,存放的是i的地址
    printf("&p=%p\n",&p);	//	p的地址,一块独立的指针空间
    printf("*p=%p\n",*p);		//p所指的i中的内容
    exit(0);
}
理解一级指针与二级指针关系:
#include <stdio.h>

int main()
{
    int i = 1;
    int *p = &i;   //可以看作是int*  p, 定义一个指针类型的一级指针p,然后把i的地址赋给p
    int **q = &p;  //可以看作是int** q, 定义一个指针类型的二级指针q,然后把p的地址赋给q

    printf("sizeof(i) = %d\n",sizeof(i));
    printf("sizeof(p) = %d\n",sizeof(p)); 

    printf("i = %d\n",i);     //  i = 1
    printf("&i = %p\n",&i);   // &i = 000000000061FE1C

    printf("p = %p\n",p);    //  p = 000000000061FE1C
    printf("&p = %p\n",&p);  // &p = 000000000061FE10
    printf("*p = %d\n",*p);  // *p = 1

    printf("q = %p\n",q);     // q = 000000000061FE10
    printf("&q = %p\n",&q);   // &q = 000000000061FE08
    printf("**q = %d\n",**q); // **q = 1

    return 0;
}
输出:
	sizeof(i) = 4
    sizeof(p) = 8
     i = 1
    &i = 000000000061FE1C
     p = 000000000061FE1C
    &p = 000000000061FE10
    *p = 1
     q = 000000000061FE10
    &q = 000000000061FE08
    **q = 1

3、直接访问与间接访问

在这里插入图片描述
直接访问:直接访问变量的值或地址

间接访问:通过其他变量访问

4、空指针与野指针

指针定义:int *p =NULL
(指针定义为NULL,是防止野指针的产生,如果你不清楚指向谁,就定义指针为NULL)
野指针是非常危险的,一定要让指针有去处

5、空类型

void *q=NULL (void类型的指针是一个万金油,它与任何指针类型都可以相互赋值)

6、定义与初始化的书写规则

int i=1int *p=&i
int **q =&i

7、指针运算

​ &取地址 *取值 关系运算 ++ –

8、指针与数组

​ 指针与一维数组
​ 指针与二维数组
​ 指针与字符数组
​ 字符指针:
​ 字符数组:

9、const 与指针

​ 用const修饰一个变量(定义时并赋值),表示将这个变量常量化,其数值保持不变

   const int a;int const a;
常量指针:

​ 指向常量的指针,即p的指向的内存可以变,P指向的数值内容不可变

const int *p;
*int const p ; //先const后p(记忆方法)
​ const修饰的是
p,说明*p不能变,但是p的指向可以变,可以通过其他定义其他来改变这个变量的值

🌰
int main()
{
    int i = 1;
    int j = 100;
    const int *p = &i;

	i = 10; //正确:i的值可以变
	*p = 10;//错误:const 修饰*p ,*p不能改变
	 p = &j;//正确:指针的指向可以改变
}
指针常量:

​ 本质是一个常量,而用指针修饰它,即p的指向的内存不可以变,但是p内存位置的数值可以变
int *const p; //先int * 后const(记忆方法)
const修饰的是p,说明p的值不能变,即p的指向不能变

🌰 
 int main()
{
    int i = 1;
    int j =100;
    int * const p = &i;

    i = 10;//正确
    p = &j;//错误:const修饰的p,p的指向不能改变
   *p = 10;//正确:p的值可以改变

	printf("%d\n",*p);
}

const int *const p; 是指针常量也是常量指针,即指向常量的常量指针,
​ 即p的指向不能变,指向的目标变量的值也不能变

🌰
int main()
 {
    int i = 1;
    int j =100;
	const int * const p = &i;

 	p = &j;//错误:后面的const修饰的p,p的指向不能改变
	*p = 10;//错误:前面const修饰*p,*p的值也不可以改变

	printf("%d\n",*p);
}

10、指针数组与数组指针

数组指针:表示的是一个指针,该指针指向的是一个数组
​ 【存储类型】 数据类型 (*指针名) 【下标】 = 值

 🌰:int (*p)[3];->  type name ;-> int[3]  *p ;定义了一个指针变量,指向了一个有3int型元素的数组,即指向int[3]

指针数组:表示的是一个数组,而数组中的每一个元素都是指针
​ 【存储类型】 数据类型 * 数组名【长度】

🌰:  int * arr[3];->  type name ;-> int *[3] arr ;定义了一个数组名为arr,数组中3个元素,每一个元素都是int *的指针,即int *[3],

11、多级指针

在这里插入图片描述

七、函数

1、函数的定义

数据类型 函数名 (【形式参数说明表】)
(【数据类型 形参名,数据类型 形参名】)

int main(int argc, char *argv[])
注:int 表示返回的数据类型

**argc** 是 argument count的缩写,表示传入main函数的参数个数;
**argv** 是 argument vector的缩写,表示传入main函数的参数序列或指针,并且第一 个参数argv[0]一定是程序的名称,并且包含了程序所在的完整路径,所		以确切的说需要我们输入的main函数的参数个数应该是argc-1个;

2、函数的传参

值传递
在这里插入图片描述

//函数传参:值传参、
#include <stdio.h>

int swap_value(int a,int b)  //值传参:将main主函数中的参数以数值的形式传给被调用的函数
{
    int tmp;
    
    tmp = a;
    a = b;
    b= tmp;

    return 0;
}

int main()
{
    int i =3,j =5;

    swap_value(i,j); //值传参
    printf("i = %d\nj = %d\n",i,j);
    return 0;
}
输出:i=3,j=5
并没有起到交换i与j的作用,如上图,只是新开辟出一块地址,进行了交换,仅i,j名字是一样的,但根本不是一回事

地址传参

在这里插入图片描述

//函数传参:地址传参

#include <stdio.h>

void swap_address(int *p,int *q) //地址传参:地址传参数要以指针类型来接收
{
    int tmp;

    tmp = *p;
    *p = *q;
    *q = tmp;
}

int main()
{
    int i =3,j =5;

    swap_address(&i,&j);  //地址传参
    printf("i = %d\nj = %d\n",i,j);

    return 0;
}
输出:i=5,j=3
上面这个函数达到了交换数的目的,通过另外一个函数达到修改其他函数的目的,一般用地址传递

全局变量

3、函数的调用

​ 函数调用
递归:一个函数,直接或间接调用自身

/*递归调用,实现斐波那契数列
   1,1,2,3,5,8,13,21,34.....
   n=(n-1) + (n-2)
   n-1 = (n-1-1) + (n-1-2)
   n-2 = (n-2-1) + (n-2-2)
  第一项  1=1
  第二项  2=1
  用法:输入n,(n表示第n项),输出斐波那契数列第n项
*/

#include <stdio.h>

int fib(int n)
{
    if(n < 1)
        return -1;
    if(n == 1 || n == 2)
        return 1;
    return fib(n-1) + fib(n-2);//关键步骤:递归调用
}

int main()
{
    int n;
    int res;

    scanf("%d",&n);

    res = fib(n);
    printf("fib[%d]= %d\n",n,res);
    return 0;
}

4、函数与数组

函数与一维数组

模块化函数与一维数组之间如何传参,如何定义接收的数组的类型,然后在被调用函数中输出

#include <stdio.h>
#include <stdlib.h>

void print_arr(int *p, int n)    // main函数传一个数组过来可以用int *p接收
{
    int i;
    printf("%s:%d\n",__FUNCTION__,sizeof(p));  //指针的大小,在64位处理器均为8个字节
    
    for(i = 0;i < n; i++)
        printf("%d ",*(p+i));
    printf("\n");
}

void print_arr2(int p[],int n)  //也可以用int p[],因为在表示形参时,一个[]相当于*
{
    int i;

    for(i =0; i< n; i++)
        printf("%d ",p[i]);
    printf("\n");

}

int main(int agrc, char **argv)  //第二个形参也可以表示为char *argc[]
{
    int a[] = {1,3,5,7,9};

    printf("%s:%d\n",__FUNCTION__, sizeof(a));  //数组的大小

    print_arr(a,sizeof(a)/sizeof(*a));
}

输出:
main:20
print_arr:8
1 3 5 7 9

函数与二维数组

模块化函数与二维数组之间如何传参,如何定义接收的数组的类型,然后在被调用函数中输出

#include <stdio.h>
#include <stdlib.h>

#define M 3
#define N 4

void print_arr(int *p,int n)   //将一个二维数组看成一个大的一维数组
{
    int i,j;
   
    printf("sizeof(p) = %d\n",sizeof(p));

    for(i =0;i < n; i++)
        printf("%d ",p[i]);
    printf("\n");
}

void print_arr1(int (*p)[N], int m,int n)  //定义一个数组指针,维数为列,区分行和列
{
    int i,j;

    printf("sizeof(p) = %d\n",sizeof(p));//8

    for(i = 0;j < m; j++)
    {
        for(j =0 ;j < n;j++)
            printf("%4d ",*(*(p+i)+j));
        printf("\n");
    }

}

float average_score(int *p,int n)  //求平均值
{
    float sum = 0;
    int i;

    for(i < 0;i < n; i++)
        sum += p[i];
    return sum/n;

}

//指针函数:指的是某一个函数的返回值为一个指针
int * find_num(int (*p)[N],int num)
{
    if(num > M-1)    //当传过来的num值大于行数时,整形类型返回值是-1,
        return NULL;  //指针类型返回值是空NULL
    return *(p+num);
}


int main()
{
    int i,j;
    int a[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};
    float ave;
    int num = 0 ;
    int *res;

#if 0    //第一种 :把三行四列的二维数组当成一个大的有12个元素的一维数组
	print_arr(&a[0][0],M*N); //传二维数组的首地址,再传共有多少个数据
            			//  也可以是a*,即把二维数组当作一个大的一维数组
           			 //*a  == *a(a+0) == a[0]  这种做法都是将行指针转化为列指针
#endif

#if 1  //第二种:有区分行和列,
    print_arr1(a,M,N);   //a的本质是一个指向数组的指针,即数组指针
    printf("sizeof(a) = %d",sizeof(a)); //48
#endif

#if 0
    ave = average_score(*a,M);  //求平均值
    printf("ave = %f\n",ave);
#endif

#if 0
//找某一行的数据并 输出
    find_num(a,num);//传行指针
#endif 

#if 0
//用指针函数,返回值为指针,需要定义一个指针来接收
    res = find_num(a,num);
    if(res != NULL)
    {
        for(i = 0; i < N; i++)
            printf("%d ",res[i]);
    printf("\n");
    }
#endif

    exit(0);
}

5、函数与指针

指针函数(是一个函数,函数的返回值是指针)
返回值 * 函数名 (形参)

int * fun(int);

int main()
{
    int i,j;
}

函数指针 (指的是一个指针,指针的指向是函数)
​ 类型 (*指针)(形参);

🌰
int (*p)(int); //定义一个指针,该指针指向一个函数
int *p;//定义一个指针,该指针指向一个int整型
float *p;//定义一个指针,该指针指向一个float浮点型

通过函数理解函数指针

函数:

int add(int a,int b)
{}

int main()
{
    int ret;
    ret = add(a,b);
}

函数指针,即定义一个指针,该指针指向函数

int main:()
{
	int ret;
    int (*p)(int,int);//本质为定义一个int (int,int) *p,
                           //即定义一个指针,该指针指向一个函数
    p = add;   //add也可以加& -> p = &add;
    ret = p(a,b);  //也可以 ret = *p(a,b);
}

🌰

//函数指针
#include <stdio.h>
#include <stdlib.h>

int add(int a,int b)
{
    return a+b;
}

int sub(int a,int b)
{
    if(a > b)
        return a - b;
    else 
        return b - a;
}

int main()
{
    int a =3,b =5;
    int ret;
    int i;
    
//函数指针
    int (*p)(int,int);
    int (*q)(int,int);
    p = add;
    q = sub;

   // ret = add(a,b);
    ret = p(a,b);
    printf("%d\n",ret);

    ret = q(a,b);
    printf("%d\n",ret);

    exit(0);
}

函数指针数组
类型 (*数组名【下标】) (形参);

🌰
int (*arr[N])(int);
    
int (int,int)  *arr[N] -->定义一个函数指针数组,
	 这是一个数组,数组中每一个元素都是指针,每个指针都指向函数
即
	int (*arr[N])(int,int);

	arr[0] = 函数1;
	arr[1] = 函数2;
	 …………
//函数指针
#include <stdio.h>
#include <stdlib.h>

int add(int a,int b)
{
    return a+b;
}

int sub(int a,int b)
{
    if(a > b)
        return a - b;
    else 
        return b - a;
}

int main()
{
    int a =3,b =5;
    int ret;
    int i;

    int (*funcp[2])(int,int);  //函数指针数组
    funcp[0] = add;
    funcp[1] = sub;

    for(i = 0;i < 2;i++)
    {
        ret = funcp[i](a,b);
        printf("%d\n",ret);
    }

    exit(0);
}

指向指针函数的函数指针数组

    int *(*funcp[N])(int)

八、构造类型

结构体

1、产生及意义

​ 数组只能存储一种类型,结构体可以存储多种类型

2、类型描述

​ struct 结构体名 // 命名习惯后加-st
​ {
​ 数据类型 成员1 ;
​ 数据类型 成员2 ;
​ …
​ };

🌰1:
    struct student_st      //定义结构体类型
    {
        int id;
        char name[128];
        int math;
        int chinese;
    };
    struct student_st stu1,stu2; //声明两个结构体类型的变量stu1,stu2
🌰2:
    struct student_st     
    {
        int id;
        char name[128];
        int math;
        int chinese;
    }stu1,stu2;    //定义类型的同时声明变量
🌰3: 
    struct                
    {
        int id;
        char name[128];
        int math;
        int chinese;
    }stu1,stu2;   //直接声明变量
3、嵌套定义
4、定义变量(变量、数组、指针),初始化及成员引用
结构体数组:
🌰
struct student_st //定义结构体类型
{
    int id;
    char name[128];
    int math;
    int chinese;
};
struct student_st  stu[10];//声明一个结构体类型的数组

🌰
struct student_st //定义结构体类型
{
    int id;
    char name[128];
    int math;
    int chinese;
}stu[N];   定义一个结构体类型同时声明一个数组变量
结构体指针:
 定义:struct 结构体类型名 * 指针变量名
成员引用:

变量名方式: 变量名.成员名 //变量名指的是结构体的名字
指针方式: 指针 ->成员名 //指针指的是结构体指针的名字
或 (指针).成员名 //小括号不能少,因为.的优先级比要高

🌰
struct student_st               
{
    int id;
    char name[128];
    int math;
    int chinese;
}stu1;  

​ main:
​    通过变量名访问:   stu1.id
​    通过指针访问:
​    struct student_st *pstu;  //定义一个结构体指针变量*pstu,并使*pstu指向结构体变量stu1
​   	 pstu->id;
         pstu->name;(*p).id;
结构体指针数组:
struct student_st               
{
    int id;
    char name[128];
    int math;
    int chinese;
}stu1[5];   //定义一个结构体类型并声明一个数组变量

​main:struct student_st *p;
​   p = stu1;  //把结构体数组stu1的首地址赋给指针变量p后,p就指向了结构体数组的第0个元素stu1[0]
​	p++;    //可使结构体指针依次指向结构体数组的各个元素
结构体 和 函数:

函数的参数类型是结构体/结构体指针:

struct student_st      //定义结构体类型
{
    int id;
    char name[128];
    int math;
    int chinese;
};

🌰//被调用函数,形参data是  结构体变量
int func(struct student_st data)  
{}int main(){struct student_st stu1;func(stu1);   //直接传结构体的值--->值传参}

🌰//被调用函数,形参pdata是  结构体指针变量int func1(struct student_st *pdata){}int main(){struct student_st stu1;func1(&stu1);  //传的是结构体的地址-->地址传参}
函数返回结构体类型的值/结构体指针 ------> 结构体类型的函数:

​ struct 结构体类型名 函数名(形参)
​ {
​ 函数体
​ }

🌰
struct student_st      //定义结构体类型
{
    int id;
    char name[128];
    int math;
    int chinese;
};

struct student_st func2(struct student_st data)  //定义一个结构体类型的函数,且形参也是结构体
{
    struct student_st tmp;  //定义一个结构体类型的参数
    ……;

    return tmp; //返回值的类型是结构体
}int main(){struct student_st res,stu2;
​        res = func2(stu2);  //用结构体类型来接收返回值}
5、占用内存空间大小
6、函数传参(值传参,地址传参)

共用体

1、产生及意义
2、类型描述

​ union 共用体名
​ {
​ 数据类型 成员名1;
​ 数据类型 成员名2;
​ }

3、嵌套定义
4、定义变量(变量,数组,指针),初始化及成员引用
5、占用内存空间大小
6、函数传参(值传参,地址传参)
7、位域

大端小端

​ 大端:数据的低位保存在高地址中 C51
​ 小端:数据的低位保存在低地址中


枚举

enum 标识符
{
成员1,
成员2, //用逗号分隔,最后一个不用逗号
……
}; //和结构体一样记得加分号

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值