zoukankan      html  css  js  c++  java
  • C语言 结构体

    结构体

    1.声明结构的形式

    1.1第一种形式

    上面去声明结构

    下面去定义变量

    #include <stdio.h>
    struct date {//声明:struct 结构名 {};
    	int month;
    	int day;
    	int year;
    };
    int main() {
    	struct date today;//使用结构的时候前面要跟上结构的名字
    	today.month=07;
    	today.day=31;
    	today.year=2014;
    	printf("Today's data is %i-%i-%i.\n",
    	       today.year,today.month,today.day
    	      );
    	return 0;
    }
    
    • 在函数内部声明的结构类型只能在函数内使用
    • 所以我们通常在函数外部声明结构类型,这样可以被多个函数所使用了

    1.2第二种形式

    没有结构的名字,p1和p2是一种无名结构,里面有x和y,不会在其他地方使用

    struct{
        int x;
        int y;
    }p1,p2
    //p1和p2里面有x,y
    

    1.3第三种形式

    struct point{//定义结构
        int x;
        int y;
    }p1,p2;//声明变量
    //p1和p2都是point里面的有x和y的变量
    

    2.结构变量

    调用形式:变量名.成员名

    2.1结构变量的初始化

    可以给特定的值进行初始化

    • 方位为{值1,值2,值3}按照顺序给值,先定义的为第一个值,以此类推

    可以指定结构成员进行初始化

    • 方法为{.成员变量1,.成员变量2....}
    • 没有给值的成员变量的值,会初始化为0和数组类似
    #include <stdio.h>
    struct date {
    	int month;
    	int day;
    	int year;
    };
    int main() {
    
    	struct date today= {07,31,2014};
    	struct date thismonth= {.month=7, .year=2014};
    
    	printf("Today's data is %i-%i-%i.\n",
    	       today.year,today.month,today.day
    	      );
    	printf("This month is %i-%i-%i.\n",
    	       thismonth.year,thismonth.month,thismonth.day
    	      );
    	return 0;
    }
    //Today's data is 2014-7-31.
    //This month is 2014-7-0.
    

    3.结构成员

    • 结构的单元可以是不同的类型,数组中的单元必须是同一类型
    • 结构同 . 运算符和名字访问其成员,数组用 数组名[下标]来访问

    4.结构运算

    要访问整个结构,直接结构变量的名字

    • 对于整个结构,可以做赋值、取地址,也可以传递给函数做参数
    pl =(struct point){5,10};//把{5,10}强制转换为 point 结构变量
    pl.x=5;
    pl.y=10;
    
    p1=p2; //相当于p1.x=p2.x;pl.y=p2.y;
    

    例如:

    #include <stdio.h>
    struct date {
    	int month;
    	int day;
    	int year;
    };
    int main() {
    
    	struct date today;
    	today=(struct date) {
    		07,31,2014
    	};
    	struct date day;
    	day=today;
    	printf("Today's data is %i-%i-%i.\n",
    	       today.year,today.month,today.day
    	      );
    	printf("The day's data is %i-%i-%i.\n",
    	       day.year,day.month,day.day
    	      );
    	return 0;
    }
    

    5.结构指针

    和数组不同,结构变量的名字并不是结构变量的地址,必须使用&运算符

    struct date *pDate = &today;
    
    #include <stdio.h>
    struct date {
    	int month;
    	int day;
    	int year;
    };
    int main() {
    
    	struct date today;
    	today=(struct date) {
    		07,31,2014
    	};
    	struct date day;
    	day=today;
    	struct date *pDate = &today;
    	printf("Today's data is %i-%i-%i.\n",
    	       today.year,today.month,today.day
    	      );
    	printf("The day's data is %i-%i-%i.\n",
    	       day.year,day.month,day.day
    	      );
    	      
    	printf("address of today is %p\n",pDate); 
    	return 0;
    }
    

    6.结构作为函数的参数

    int number0fDays(struct date d)
    
    • 整个结构可以作为参数的值传入函数
    • 这时候是在函数内新建一个结构变量,并复制调用者的结构的值
    • 也可以返回一个结构

    案例:

    6.1计算明天的日期

    #include <stdio.h>
    #include <stdlib.h>
    struct date {
    	int month;
    	int day;
    	int year;
    };
    bool isLeap(struct date d); //这个函数用于判断是否是闰年 
    int number0fDays(struct date d);//这个函数用于判断输入的月份有几天 
    int main() {
    	struct date today,tomorrow;
    	printf("Enter today's date (mm dd yyyy):");
    	scanf("%i %i %i",&today.month,&today.day,&today.year);
    	//这里可以看到取成员变量的优先级要高一些,会把读到的值交给结构体中的成员变量
    
    	if( today.day != number0fDays(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;
    	}
    	printf("tomorrow's data is %i-%i-%i.\n",
    	       tomorrow.year,tomorrow.month,tomorrow.day
    	      );
    
    	return 0;
    }
    
    int number0fDays(struct date d) {
    	int days;
    
    	const int daysPerMonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    	//一个字面量int类型的数组 
    	if( d.month==2 &&isLeap(d)) { //若为闰年 2月就为29天 
    		days=29;
    	} else {
    		days=daysPerMonth[d.month-1];
    	}
    	return days;
    }
    //判断是否是闰年,闰年的二月有29天
    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;
    }
    

    7.输入结构

    • 没有直接的方式可以一次scanf一个结构

    • 如果我们打算写入一个函数来读入结构

      #include <stdio.h>
      
      struct point{
      	int x;
      	int y;
      }; 
      
      void getStruct(struct point p);
      void output(struct point p);
      int main()
      {
      	struct point y={0,0};
      	getStruct(y);
      	output(y);	
      	return 0;
      } 
      
      void getStruct(struct point p)
      {
      	scanf("%d",&p.x);
      	scanf("%d",&p.y);
      	printf("%d,%d\n",p.x,p.y);
      }
      
      void output(struct point p)
      {
      	printf("%d,%d\n",p.x,p.y);
      }
      //12 23
      //12,23
      //0,0 可以看到值并没有传回来,再一次调用还是0和0
      
    • 所以在函数中的p与main中的y是不同的

    解决方案:

    1. 在这个输入函数中,完全可以创建一个临时的结构变量,然后把这个结构返回给调用者
    #include <stdio.h>
    
    struct point{
    	int x;
    	int y;
    }; 
    
    struct point getStruct(void);
    void output(struct point p);
    int main()
    {
    	struct point y={0,0};
    	y=getStruct(); 
    	output(y);	
    	return 0;
    } 
    
    struct point getStruct(void)
    {	
    	//定义一个结构变量,并返回回去 
    	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);
    }
    /*12 23
    12,23
    12,23*/
    
    1. 利用结构体指针参数
    #include <stdio.h>
    
    struct point{
    	int x;
    	int y;
    }; 
    
    struct point *getStruct(struct point *p);
    //传入一个struct point类型的指针p,并返回一个struct point类型的指针getStruct 
    void output(struct point p);
    //传入一个 struct point类型 p 
    void print(const struct point *p); 
    //传入一个 struct point的指针 p 
    int main()
    {
    	struct point y={0,0};
    	getStruct(&y);
    	output(y);
    	output(*getStruct(&y));	
    	print(getStruct(&y));
        *getStruct(&y)=(struct point){1,2,3};
    	
    	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);
    	
    } 
    

    8.指向结构的指针

    struct date{
    	int month;
        int day;
        int year;
    }myday;
    
    struct date *p= &myday;
    
    (*p).month =12;//一般不建议这么写
    p->month =12;
    
    • 用->表示指针所指的结构变量中的成员

    9.结构数组

    struct date dates[100];
    struct date dates[]={{4,5,2005},{2,4,2005}}
    //dates[1]:{4}
    

    示例:

    #include <stdio.h>
    struct time {
    	int hour;
    	int minutes;
    	int seconds;
    };
    struct time timeUpdate(struct time now);
    
    int main(void) {
    	struct time testTimes[5]= {
    		{11,59,59},{12,0,0},{1,29,59},{23,59,59},{19,12,17}
    	};
    	int i;
    	for (i=0; i<5; ++i) {
    		printf("Time is %.2i:%.2i:%.2i \n",
    		       testTimes[i].hour,testTimes[i].minutes,testTimes[i].seconds);
    
    		testTimes[i]=timeUpdate(testTimes[i]);
    		printf("...one second later it's %.2i:%.2i:%.2i \n",
    		       testTimes[i].hour,testTimes[i].minutes,testTimes[i].seconds);
    	}
    	return 0;
    }
    
    struct time timeUpdate(struct time now) {
    	++now.seconds;
    	if(now.seconds ==60) {
    		now.seconds=0;
    		++now.minutes;
    		if(now.minutes==60) {
    			now.minutes=0;
    			++now.hour;
    			if(now.hour==24) {
    				now.hour=0;
    			} 
    		}
    	}
    	return now; //返回结构体 
    }
    

    10.结构中的结构

    struct dateAndTime{
    	struct date sdate;
    	struct time stime;
    }; 
    

    10.1嵌套的结构

    struct point{
    	int x;
        int y;
    };
    struct rectangele{
    	struct point pt1;
        struct point pt2;
    };
    如果有变量
        struct rectangele r;
    	r.pt1.x,r.pt1.y //.pt1是一个结构
        r.pt2.x和r.pt2.y
            
    如果有变量定义:
        struct rectangele r,*rp;
    	rp=&r;
    那么下面的四种运算形式是等价的
        r.pt1.x
        rp->pt1.x
        (r.pt1).x
        (rp->pt1).x
        但是没有rp->pt1->x(因为pt1不是指针)
    
  • 相关阅读:
    使用postman时请求参数中包含特殊字符问题,如加号传到后台变成空格
    okhttp3报错:java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
    Eclipse的知识积累
    partition 取数据中相同字段数据中取时间最大的一个值 并只保留一条
    理解Session缓存机制 操纵持久化对象
    Hibernate的检索策略
    LINQ介绍
    .Net 一对一的双向关联Map写法
    Hibernate多态查询
    NHibernate实战[转 2012 gogogo]
  • 原文地址:https://www.cnblogs.com/DL50/p/15419901.html
Copyright © 2011-2022 走看看