C language_0329 notes_structure: structure as function parameter/scanf input structure variable value/structure array/structure and structure/infinite nesting

Table of contents

11.2.2 Structures and functions

scanf input structure

 Solution (1): Temporary variables

Solution (2): Structure pointer as parameter (more recommended)

11.2.3 Structure within structures

structure array

structure within structure

 Nested structure (rectangle defined by two diagonal points)

 array of structures within structures 


11.2.2 Structures and functions

Data types such as int and float can be used as parameters of functions, and structures can also be used as a data type (as mentioned above)

int NumberOfDays(struct date d)

  • The entire structure can be passed into the function as the value of the parameter 
  • At this time, a new structure variable is created within the function and the value of the caller's structure is copied .
  • The return value can also be a structure
  • (The above characteristics are completely different from arrays)

example


 //求明天的日期
#include<stdio.h>
#include<stdbool.h>
//定义了一个 结构 类型,里面包含三个int类型的变量 
struct date{
    int month;
    int day;
    int year;
};
 
bool isLeap(struct date d);//判断是否是闰年函数
int numberOfDays(struct date d);//给出每个月有几天的函数
 
int main()
{
    struct date today;
    struct date tomorrow;
 	int sig=1;
    printf("Enter today's date (mm dd yyyy):");
    scanf("%i %i %i",&today.month,&today.day,&today.year);
//%i是旧写法,和%d一样是输出十进制整数的格式控制符
//&today.month是先进行点运算,取成员month,再将输入的数据用&取地址。
    //因此点运算优先级高
 
 
//若今天不是本月最后一天(也就是本月的天数)
//明天就是天数加一
//	printf("today mm %d\n",today.month);
	//printf("这个月有%d天\n",numberOfDays(today));//这个月有32764天
if(today.day > numberOfDays(today) ||
	today.month >12 ){
		sig =0;
	printf("非法输入,请检查输入是否正确");
	
}
if(today.day != numberOfDays(today)){
    tomorrow.day = today.day+1;
    tomorrow.month = today.month;
    tomorrow.year = today.year;
//12月的最后一天,那么第二天就是第二年
}else if(today.month == 12){
    tomorrow.day = 1;
    tomorrow.month = 1;
    tomorrow.year = today.year+1;
}else{
//不是12月,而且今天是本月最后一天,明天就是下个月第一天
    tomorrow.day = 1;
    tomorrow.month = today.month+1;
    tomorrow.year = today.year;
}
if (sig){
	printf("Tomorrow's date is %i-%i-%i.\n",
    tomorrow.month,tomorrow.day,tomorrow.year);
}
 
return 0;
}
int numberOfDays(struct date d) //给出每个月有几天的函数
{
    int days=0;
    const int daysPerMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};
 	//printf("函数中的月份 %d\n",d.month); // 3
 	//printf("daysPerMonth[d.month-1]: %d\n",daysPerMonth[d.month-1]); //31
    if(d.month == 2 && isLeap(d))//【if语句里面 判断相等!!一定要用==啊啊啊】 
        days = 29;
    else{
    	days = daysPerMonth[d.month-1]; 
		//因为数组下标从0开始,month.1对应数组【0】
	}
       //printf("days %d\n",days); 
    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;
}

//Structure variables can be passed directly between functions

bool isLeap(struct date d); //Determine whether it is a leap year function
int numberOfDays(struct date d); //A function that gives the number of days in each month

scanf input structure

  • There is no direct corresponding format control character corresponding to an entire structure type, because it contains various types of user-defined data.
  • If you plan to use a function to read in the structure, such as:
  • #include<stdio.h>
    struct point{
        int x;
        int y;  };
     
    void getStruct(struct point);
    void output(struct point);
    void main(){
        struct point y = {0,0};
        getStruct(y);
        output(y);
    }
     
    void getStruct(struct point p){
    //接收到y结构变量的值,是另外一个结构变量
    //因此执行完这个程序后,y不会改变,output函数输出0,0
        scanf("%d",&p.x);
        scanf("%d",&p.y);
        printf("getstruct:%d,%d\n",p.x,p.y);
    }
    void output(struct point p){
        printf("output:%d,%d\n",p.x,p.y);
    }

 Result: (the value in main is not changed) but because what is passed into the function is a clone of the outer structure , not a pointer to the content

 Solution (1): Temporary variables

 The idea of ​​using the function to read the structure above is good, but since the passed-in function is a clone of the outer structure rather than a pointer to the content, there is a method:

In the incoming function, create a temporary structure variable, and then return the temporary structure to the caller

#include<stdio.h>
struct point{
    int x;
    int y;  };
 
struct point getStruct(void);
void output(struct point);
 
int main()
{    
    struct point y = {0,0};
    y = getStruct();//这个函数不需要传入参数
//结构之间可以直接赋值,将临时结构p赋给y
    output(y);
}
 
//一个返回类型为结构的函数
struct point getStruct(void)//这个函数不需要传入参数 但是它返回一个结构类型 
{
    struct point p;
    scanf("%d",&p.x);
    scanf("%d",&p.y);
    printf("getStruct: %d,%d\n",p.x,p.y);
    return p;//但是它返回一个结构类型 
}
 
void output(struct point p){
    printf("output: %d,%d\n",p.x,p.y);
}

Solution (2): Structure pointer as parameter (more recommended)

 When you pass a large structure to a function, passing a pointer is more efficient than copying . Because the way C transfers structures is by value, it takes both space and time to create a structure in the called function that is exactly the same as the outside.

There is a simpler notation to represent the members of the structure variable pointed to by the pointer : ->

struct date{int month; int day; int year;} myday; //The structure type is declared and the structure variable is created

struct date *p = &myday; //Take out the address of myday and give it to the pointer p

——Member (month) in the structure variable (myday) pointed to by the pointer——

(*p).month = 12; //Writing 1

p->month = 12; //Writing 2, in Chinese it is called the month pointed to by p

Knowing this simplified writing method, the program in solution 1 can be written as:

#include<stdio.h>
struct point{
    int x;
    int y;  };

//函数的参数和返回类型现在都是结构指针
struct point* getStruct(struct point*);//传入指针  返回指针 
void output(struct point);//传入结构变量 
void print(const struct point *p);//传入结构指针(常量) 
 
int main()
{    
    struct point y = {0,0};
    getStruct(&y);//int *p=&a; 得到p(指向输出的xy) //getstruct函数返回的是指针p 也就是地址
    output(y);
    output(*getStruct(&y));
//output函数对其进行了*运算(地址上面的值)
//最后用%d 输出 printf函数拿出了地址 所以要用->指向指针p对应的地址
//才能用%d输出
/************************************************************************************************ */
//这里的参数意义:
//*代表了他要取出指针指向的变量,而此时指针指向的是另一个函数的返回值
//所以实际上传入的参数就是上一个函数的返回值
    print(getStruct(&y)); //getStruct得到的指针 传给print print继续操作 
//还可以做的是:
	*getStruct(&y) = (struct point){1,2};
//为什么?因为左边实际上是个变量,这完全符合编译规则和语法
}
 
//传入指针操作之后又返回,好处是可以在之后继续调用这个指针
struct point* getStruct(struct point *p) //返回指针 struct point * 参数指针 
{
    scanf("%d",&p->x); //取p所指的y的x
    scanf("%d",&p->y); //取p所指的y的y
    printf("getStruct:%d,%d\n",p->x,p->y);
    
    return p;
    //返回得到的参数p
}
 
	void output(struct point p){
	    printf("output:%d,%d\n",p.x,p.y);
	}
	 
	void print(const struct point *p)
	{
	//由于只进行输出,传入指针可以是const
	    printf("print: %d %d",p->x,p->y);
	}

11.2.3 Structure within structures

structure array

An array is defined, and each unit in the array is a variable defined by myself.

int a[100] //Basic type

struct time a[100] //type declared by yourself

example:

struct date dates[100];
//定义了一个结构数组,100字节大小的数组,每一个单元都是一个结构变量
struct date dates[]={
    {4,5,2005},//dates[0]
    {2,4,2005} //dates[1]
};
 
//调用内部数据:
printf("%i",dates[0].day);

printf("%.2f");

Indicates that it is output in real type (also a floating point type) and retains two decimal places. If there are not enough two digits after the decimal point, it is represented by 0 or a random number. If it exceeds 2 digits, it will be rounded

structure within structure

Structural variables can be basic variable types or structural variables.

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

 Nested structure (rectangle defined by two diagonal points)

struct point{
    int x;
    int y;
};
 
struct rectangle{
    struct point p1;
    struct point p2;
};
 
int main()
{
    struct rectangle r;
}
就可以有r.p1.x、r.p1.y、r.p2.x、r.p2.y等
来表示每个点
 

If there is
    struct rectangle r,*rp;
    rp = &r;,

there are four equivalent forms :

  1. r.p1.x takes out the x of p1 in r
  2. rp->p1.x x in p1 pointed by rp
  3. (r.p1).x It makes no difference whether you add parentheses or not, because the dot operator works from left to right.
  4. (rp->p1).x Same as above, because the pointer points to it first, and then the structure is fetched
  5. But there is no rp->p1->x (because p1 is not a pointer, it is a structure, and of course it cannot point to anything else)

 array of structures within structures 

Infinite nesting dolls:

#include<stdio.h>
 
struct point{
    int x;
    int y;
};
struct rectangle{
    struct point p1;
    struct point p2;
};
 
void printRect(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 i;
    struct rectangle rects[]=
    {    {
   
   {1,2},{3,4}},//{ 1 2, 3 4} 12是p1 34是p2
         {
   
   {5,6},{7,8}}
    }
//rects[0].p1.x和y == {1,2}
//rects[0].p2.x和y == {3,4}
 
    for(i=0;i<2;i++)
    printRect(rects[i]);
 
return 0;
}

Guess you like

Origin blog.csdn.net/Shmily_as33/article/details/129835939