4.2 结构类型——结构

本文详细介绍了C语言中的结构体,包括结构体的声明、初始化、成员访问、结构体运算、结构体指针、作为函数参数的使用,以及结构体数组、嵌套结构和结构体数组等高级用法。
摘要由CSDN通过智能技术生成

1. 结构

#include<stdio.h>

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

    struct date today;

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

    // Today is 2017-2-16
    printf("Today is %i-%i-%i\n", today.year, today.month, today.day);
    return 0;
}

2.声明在函数内外

和本地变量一样:

  • 在函数内部声明的结构类型,只能在函数内部使用
  • 在函数外部声明的结构类型,可以被多个函数使用,通常在函数外部

3.声明结构的形式

    // 方式一 
    struct point {
        int x;
        int y;
    };
    struct point p1, p2;// p1 和 p2 都是point,都有x y

    // 方式二
    struct {
        int x;
        int y;
    } p1, p2; //没有声明 point, p1, p2 是一种无名结构,有 x y

    // 方式三
    struct point{
        int x;
        int y;
    } p1, p2; // p1 p2 都是point,里边有 x y 

4.结构的初始化

#include<stdio.h>

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

int main(int argc, const char *argv)
{
    struct date today = { 02, 16, 2017 };
    printf("Today is %i-%i-%i\n", today.year, today.month, today.day); // Today is 2017-2-16

    // .c 文件支持,.cpp 不支持会报错:sorry, unimplemented: non-trivial designated initializers not supported 
    struct date Month = {.year = 2017, .month = 02}; 
    printf("this month is %i-%i-%i\n", Month.year, Month.month, Month.day); // this month is 2017-2-0


    return 0;
}

5. 结构成员

变量名.成员名

#include<stdio.h>

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

int main(int argc, const char *argv)
{
    struct date today = { 02, 16, 2017 };
    printf("Today is %i-%i-%i\n", today.year, today.month, today.day); // Today is 2017-2-16

    return 0;
}

6.结构运算

  • 用结构变量的名字 访问整个结构
  • 对于整个结构,可以做 赋值、取地址、函数参数
    • p1 = (struct point){5, 10}; // 相当于 p1.x = 5; p1.y = 10;
    • p1 = p2; // 相当于 p1.x = p2.x; p1.y = p2.y;
#include<stdio.h>

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

int main(int argc, const char *argv)
{
    struct date today;
    today = (struct date){ 02, 16, 2017 };

    struct date day;
    day = today;
    day.year = 2015;
    printf("day is %i-%i-%i\n", day.year, day.month, day.day); // day is 2015-2-16

    return 0;
}

7. 结构指针

用 & 取结构体的地址

#include<stdio.h>

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

int main(int argc, const char *argv)
{
    struct date today;
    today = (struct date){ 02, 16, 2017};

    struct date *pDate = &today;

    printf("address of today is %p\n", today); // address of today is 000000000022FE20
    printf("address of pDate is %p\n", pDate); // address of pDate is 000000000022FE30
    printf("pDate=%X\n", *pDate); // pDate=22FE20

    return 0;
}

8. 结构作为函数参数

int numberOfDay(struct date d)

  • 整个结构可以作为函数参数,在函数内新建一个结构变量,并复制调用者的结构的值
  • 函数可以返回一个结构

输入今天的日期,打印明天的日期

#include<stdio.h>
#include<stdbool.h>

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

bool isLeap(struct date d);
int numberOfDays(struct date d);

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

    printf("输入今天的日期(mm dd yyyy):"); // 输入今天的日期(mm dd yyyy):02 16 2017
    scanf("%i %i %i", &today.month, &today.day, &today.year);

    if(today.day != numberOfDays(today)){
        tomorrow.day = today.day + 1;
        tomorrow.month = today.month;
        tomorrow.year = today.year;
    } else if(today.month == 12) {
        tomorrow.day = 1;
        tomorrow.month = 1;
        tomorrow.year = today.year + 1;
    } else {
        tomorrow.day = 1;
        tomorrow.month = today.month + 1;
        tomorrow.year = today.year;
    }

    // Tomorrow's date is 2017-2-17
    printf("Tomorrow's date is %i-%i-%i\n", tomorrow.year, tomorrow.month, tomorrow.day);

    return 0;
}

int numberOfDays(struct date d)
{
    int days;
    const int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    if(d.month == 2 && isLeap(d)){
        days = 29;
    } else {
        days = daysPerMonth[d.month - 1];
    }

    return days;
}


bool isLeap(struct date d)
{
    bool leap = false;
    if((d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0){
        leap = true;
    }
    return leap;
}

9.输入结构

没有直接的方式可以一次 scanf 一个结构,比如我们有一个函数 用于读入一个坐标的x y值,该函数中可以操作这个结果,但是怎么传出去呢?
可以在函数中,创建一个临时的结构变量,然后 返回这个结构变量

#include<stdio.h>

struct point {
    int x;
    int y;
};

struct point getPoint(void);
void printPoint(struct point);


int main(int argc, const char *argv)
{
    struct point y = {0,0};
    y = getPoint();
    printPoint(y);
    return 0;
}


struct point getPoint()
{
    struct point p;
    scanf("%d", &p.x);// 输入 2 回车 3 回车
    scanf("%d", &p.y);
    printf("getPoint x=%d, y=%d\n", p.x, p.y); // getPoint x=2, y=3 
    return p;
}

void printPoint(struct point p)
{
    printf("printfPoint x=%d, y=%d\n", p.x, p.y); // printfPoint x=2, y=3
}

10.指向结构的指针 作为参数

当传递给函数 一个很大的结构,传指针 比 结构 更高效

用 -> 表示指针所指的结构变量中的成员

#include<stdio.h>

struct point {
    int x;
    int y;
};

struct point* getPoint(struct point*);
void printPoint(const struct point*);


int main(int argc, const char *argv)
{
    struct point y = {0,0};
    getPoint(&y);
    printPoint(&y);
//  printPoint(getPoint(&y));
    return 0;
}


struct point* getPoint(struct point* p)
{

    scanf("%d", &p->x);// 输入 2 回车 3 回车
    scanf("%d", &p->y);
    printf("getPoint x=%d, y=%d\n", p->x, p->y); // getPoint x=2, y=3
    return p;
}

void printPoint(const struct point *p)
{
    printf("printfPoint p->x=%d, p->y=%d\n", p->x, p->y); // printfPoint p->x=2, p->y=3
}

11.结构数组

#include<stdio.h>

struct time{
    int hour;
    int minute;
    int second;
};

struct time timeUpdate(struct time now);

int main(int argc, const char *argv)
{

    struct time times[] = {
        {11, 59, 59},
        {12, 1, 0},
        {1, 29, 59},
        {23, 59, 59},
        {19, 12, 27}
    };

    int i;
    for(i = 0; i < 5; i++){
        printf("Time is %.2i:%.2i:%.2i\n", times[i].hour, times[i].minute, times[i].second);

        times[i] = timeUpdate(times[i]);

            printf("1s laster, Time is %.2i:%.2i:%.2i\n", times[i].hour, times[i].minute, times[i].second);
    }

    return 0;
}

// 计算1s之后的时间并返回 
struct time timeUpdate(struct time now)
{
    ++now.second;

    if(now.second == 60){
        now.second = 0;
        ++now.minute;

        if(now.minute == 60){
            now.minute = 0;
            ++now.hour;

            if(now.hour == 24) {
                now.hour = 0;
            }
        }


    }
    return now;

}

12.嵌套的结构

struct point{
    int x;
    int y;
};

struct rectangle{
    struct point p1;
    struct point p2;
};

// 如果有  struct rectangle r; 就可以有 r.p1.x  r.p2.y

// 如果有: 
struct rectangle r, *rp;
rp = &r;
// 下边四种形式是等价的 
r.p1.x;
rp->p1.x;
(r.p1).x;
(rp->p1).x; 

13.结构中的结构数组

#include<stdio.h>

struct point{
    int x;
    int y;
};

struct rectangle{
    struct point p1;
    struct point p2;
};

void printRec(struct rectangle r)
{
    printf("<%d,%d> to <%d,%d>\n", r.p1.x, r.p1.y, r.p2.x, r.p2.y);
}

int main(int argc, const char *argv)
{

    struct rectangle rects[] = {
        {{1, 2}, {3, 4}},
        {{5, 6}, {7, 8}}
    };

    int i;
    for(i = 0; i < 2; i++){
        printRec(rects[i]);
    }
    return 0;   
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值