目录
本篇主要讲结构体与函数的调用,分为两部分,第一部分是单结构体调用,第二部分是结构体数组的调用方式;
结构体的定义和赋值方式
简单说一下结构体的5种定义方式
1.
struct stu s[3] //在首部进行定义。
{
int num;
char name[30];
};//一定要注意这里的分号,定义结构体函数相当于是一条语句,需要以分号结尾。
2.
struct stu
{
int num;
char name[30];
}s[3],*p;//在末尾和结构体同时定义,可定义多个变量用逗号分隔,注意是在分号里面。p为结构体指针。
3.
struct stu
{
int num;
char name[30];
};
int main()
{
stu s[3];//可以在主函数中定义变量
4.
struct stu
{
int num;
char name[30];
};
struct stu s[3];//在函数外进行定义。这时就相当于是一个外部变量;和普通的外部变量一样。函数内可以定再次义重名变量
5.
struct //甚至可以没有类型名,直接定义变量。
{
int a;
float b;
}stu={5,3.0}; //此处的stu为结构体变量名
但此种方式并不推荐,因为只能在此末尾定义好,在函数体中没办法定义。因为省去了结构体类型名。
stu为结构体类型名,用于在函数中定义结构体变量,或者在函数调用中定义形参的类型。
s[3]为结构体变量。是一个结构体数组。
结构体的赋值方式
第一种是直接在定义时赋初值。如下;
struct stu
{
int num;
char name[30];
};
int main()
{
stu s[3]={3,"zhangsna",5,"lisi",6,"wangwu"};//可以在定义时统一赋值。
stu s[3]={{3,"zhangsna"},{5,"lisi"},{6,"wangwu"}};//这两种形式都是可以的。
第二种是在函数内进行赋值,在函数内赋值,是遵循结构体变量中的成员类型,依次赋值,不能一同赋值。
#include<string.h>
int main()
{
stu s[3];
scanf("%d%s",&s[0].num,s[0].name);//依次对应经行赋值赋值,该加取地址符的要加
s[1].num=2;//单独调出其中的成员进行赋值。
strcpy(s[1].name,"laowang");//字符串,要遵循字符串的赋值规则。
s[2]={3,"laoliu"};//这种形式是不正确的!!!
单结构体的调用方式
比较简单直接传递结构体元素或者元素地址即可。
如果传递的是元素的地址,那么函数接收的指针用不用定义成结构体类型的呢?答案是不用的,只需要定义一个和元素类型一致的指针即可。因为传递过来的仅仅是一个元素,而不是结构体。结构体指针应指向的是结构体变量的地址;
列出了一个综合型的例子,包括传递的类型和接收的类型:
#include<stdio.h>
struct stu//定义结构体类型名 stu;
{
char name[20];
int num;
float fen;
};
void fun(char *q,float n,stu *p)//定义了三种接收类型;字符型指针,实型变量,结构体指针;
{
n=36.6;
p->num=3;
printf("这是%s\n",q);
}
int main()
{
stu s={"wang",1,30.54,},*p;//定义结构体变量s和结构体指针p;
p=&s;
printf("改变前:%f,%d\n",s.fen,s.num);
fun(s.name,p->fen,&s); //三种传递方式
printf("改变后:%f,%d",s.fen,s.num);
return 0;
}
可直接进行元素的传递,和普通的变量传递方式一样,只不过结构体的元素形式为:
结构体变量的名称.成员名
指针的方式为:
(*指针).成员名 指针->成员名
fen传递的是值,所以在子函数中不会改变实际的值,而num传递的是地址,则会改变实际的值。
而如果传递的是指针,则接收的类型要是结构体类型的指针;
void fun(stu *p)//用一个结构体类型指针来接收;
{
p->num=5;
}
int main()
{
stu s={"wang",1,30.54,},*p;
p=&s;
printf("改变前:%d\n",s.num);
fun(p);
printf("改变后:%d",s.num);
return 0;
}
这同样传递的也是地址,因为p指向结构体变量s的地址;所以子函数也可以改变实际的参数值;
同一类型的结构体可以相互赋值:
struct stu//定义结构体类型名 stu;
{
char name[20];
int num;
float fen;
};
int main()
{
stu s={"wang",1,30.54,},s1;
s1=s;
printf("%d",s1.num);
结构体的嵌套:
struct ST//定义内嵌套结构体类型ST;
{
int a=5;
float b=10.5;
};
struct stu//定义主体结构体类型stu;
{
char name[20];
ST w;//定义ST类型结构体变量w;
};
int main()
{
stu s;
printf("%d",s.w.a);//输出嵌套体中的变量a;
return 0;
}
嵌套体一定要在主体之前定义,不然主结构体不清楚定义类型(即使在主函数中定义也是一样的)
嵌套体可以与主体同名,但最好不要,容易弄混;
结构体数组的函数调用方式:
int i;
stu s[3]={{"wang",1,30.54,},
{"liu",2,36.5},
{"li",3,40.6}},*p[3];//这时可以定义一个结构体指针数组与之对应;
for(i=0;i<3;i++)
p[i]=&s[i];
fun(s[1].name,p[1]->fen,&s[1]);
结构体数组的方式,类似于数组,只不过取值的方式和数组不太一样。
向函数传递结构体数组的首地址:
#include<stdio.h>
struct stu
{
char name[20];
int num;
float fen;
};
void fun(stu a[])//用一个结构体数组来接收;
{
a[0].num=3;
}
int main()
{
stu s[3]={{"wang",1,30.54,},
{"liu",2,36.5},
{"li",3,40.6}};
printf("改变前:%d\n",s[0].num);
fun(s); //将结构体数组的首地址传过去;
printf("改变后:%d",s[0].num);
return 0;
}
因为数组名指向的是数组的首元素地址,所以相当于一个指针。将结构体数组名直接传递过去,相当于传递的是首个结构体变量的地址,然后用一个结构体数组来接收即可,道理和数组向函数的传递是一样的。这种方式子函数可以接收多个结构体变量,并且可以在子函数中来改变实参的值。
结构体数组和指针
判断清楚优先级的高低,再进行运算,‘*’和‘++’是同级属于右结合,()和->是同级属于左结合;也就是从左到右;
#include<stdio.h>
struct st
{
int x;
int *y;
}*p;
int dt[4]={10,20,30,40};
st a[4]={50,&dt[0],60,&dt[1],70,&dt[2],80,&dt[3]
};
int main()
{
p=a;
printf("%d,",++p->x);// ->的优先级大于++,所以为先取值,对值进行加加;
printf("%d,",(++p)->x);//先执行括号里内容,指针移动,取内容;
printf("%d\n",(*p->y)++);//‘->’的优先级高于‘*’,所以先取y,在取y地址的内容;输出以后在对y地址的内容加加也就是20++;
};
好了谢谢大家,如果有错,请立刻指正,谢谢。