登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[学习笔记] 结构(上)

[复制链接]
发表于 2018-2-17 21:42:18 | 显示全部楼层 |阅读模式
学习笔记
学习科目: C语言结构变量
学习安排: 枚举,结构体使用,结构体指针,结构体与函数
开始时间: 2018-02-17
结束时间:
枚举
是一种用户定义的数据类型,它用enum以如下语法来声明:
enum 枚举类型的名字{名字0,,,,名字n};
枚举类型名字通常不真的使用,要用的是在大括号里的名字,
因为它们通常就是常量符号,类型是int,值依次从0到n
如:
    enum colors{red,yellow,green};
就创建了3个常量,red的值是0,yellow的值是2,依次类推

当需要一些可以排列起来的常量时,定义枚举的意义就是给
了这些常量值名字

枚举量可以作为值
枚举类型前可以加上enum作为变量类型
    void f(enum color c){
      print("%d\n",c);
    };
    可以看做 int
    但是实际上是以整数来做内部计算和外部输出的
    虽然可以看做类型,可是实际上很少(不好)用

如果有意义上排比的名字,用枚举比 const int 好用
枚举比宏(macro)好,因为枚举有 int 类型

结构声明
以下面这个代码为例
#include<stdio.h>

int main(int argc,char const *argv[])
{
    struct date{
        int month;
        int day;
        int year;
    };
    struct date today;

    today.month = 02;
    today.day = 16;
    today.year = 2018;

    printf("Today's date is %i-%i-%i.\n",
        today.year,today.month,today.day);
    return 0;
}
结构体是一些复杂类型的集合,由多个变量组成
通常我们回让结构体作全局变量,让所有函数使用
声明结构的形式

struct point{
    int x;
    int y;
};
struct point P1,P2;

struct point{
    int x;
    int y;
}P1,P2;
这两种都是一个意思,P1和P2都是point里面有x和y的值

struct{
    int x;
    int y;
}P1,P2;
P1和P2都是一种无名结构,里面有x和y

结构的初始化
可以像上面的代码一样进行初始化
也可这样
struct date today={02,16,2018};
计算机会依次的给结构内部的变量
struct date thismonth = {.month=02,.year=2018};
而没有初始化的变量的值就会是0,这点和数组一样
但是
P1 = (struct point){5,10};//相当于P1.x=51.y=10;
P1 = P2; //相当于P1.x=P2.x1.y=P2.y;
这两种运算数组是无法做的
对结构变量取地址必须要用&,数组的名字就是数组第一个单元的地址

结构可以作为函数的参数和返回值
int numberofdays(struct date d)
其实这是在函数中新建了一个结构类型,再将传入的结构的值赋值给它
这点与数组完全不一样
下面是一个使用结构的例子
以计算出明天的日期为例
#include<stdio.h>

struct date{
    int year;
    int month;
    int day;
};

int numberofdays(struct date d);

int main(int argc,char const *argv[])
{
    struct date today,tomorrow;

    printf("enter today's day(yyyy mm dd):");
    scanf("%i%i%i",&today.year,&today.month,&today.day);

    tomorrow=today;
    tomorrow.day++;     //日+1

    if(today.day == numberofdays(today)){ //如果今天事这个月的最后一天,日=1,月+1
        tomorrow.day=1;
        tomorrow.month++;
    }
    if(tomorrow.month==13){//如果月份=13,月=1,年+1
        tomorrow.month=1;
        tomorrow.year++;
    }
    printf("%i-%i-%i\n",tomorrow.year,tomorrow.month,tomorrow.day);

    return 0;
}


int isleap(int y){
    int leap = 0;
    if((y%4==0&&y%100!=0)||y%400 ==0)
        leap = 1;
    return leap;
}
int numberofdays(struct date d){
    int days;
    const int dayspermonth[]={31,28,31,30,31,30,31,30,31,30,31,30};
    if(d.month==2&&isleap(d.year)==1){//判断闰年的二月
        days = 29;
    }else{
        days=dayspermonth[d.month-1];
    }
    return days;
}
返回结构变量的例子
struct point getstruct(void){
    struct point p;
    `````
    `````
    return p;
}
返回结构大致的方法可以像上面这个例子一样,当然,我们也可以传参数进去

更推荐的,是使用结构指针,因为穿结构,需要空间,又需要时间
效率会很差

struct date{
    int month;
    int day;
    int year;
}myday;

struct date *p=&myday;//结构指针

(*p).month=12;可以这样表示结构内的成员
p->month=12;也可以这样,叫做,p所指的month

#include<stdio.h>

struct point{
    int x;
    int y;
};

struct point* getStruct(struct point* p);
void output(struct point);
void print(const struct point *p);

int main()
{
    struct point y={0,0};
    getStruct(&y);
    output(y);
    output(*getStruct(&y));
    *getStruct(&y)=(struct point){1,2};
    print(getStruct(&y));

    return 0;
}

struct point* getStruct(struct point* p){
    scanf("%d",&p->x);
    scanf("%d",&p->y);
    printf("%d %d\n",p->x,p->y);
    return p;
}

void output(struct point p){
    printf("%d %d\n",p.x,p.y);
}
void print(const struct point *p){
    printf("%d %d\n",p->x,p->y);
}
这个例子很简单,只是为了在屏幕上显示 point
但这里有2点需要注意
1.  我们可以这样
    output(*getStruct(&y));
    将函数的返回结果作为指针,因为这里返回的是地址

2.  我们设置可以对它赋值
    *getStruct(&y)=(struct point){1,2};

好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表