结构
声明结构类型
结构的声明可以放在放在函数外部和内部——这取决于你自己想要多个函数一起用还是一个单独用。
struct point{
int x;
int y;
};
{ }内部叫做结构声明,point称为结构标记,可以用来简写结构,代表结构内的声明;结构内定义的变量叫做成员(分号千万不要忘)。
这种声明方式与下面这种是不同的:
struct {
int x;
int y;
}point;
这两者之间的区别在于:
第一种可以作为一种变量类型并且声明新结构变量,如:
struct point{
int x;
int y;
};
struct point p;
而第二种是一种无结构声明的结构:
struct {
int x;
int y;
}point;
这代表着你只是暂时需要一个叫做point的结构,并不代表你有了struct point这种类型。
如果你误认为这种声明与第一种一样去声明新结构变量
struct point p;
会显示错误:
“message”: “variable has incomplete type ‘struct point’”,
当然你也可以这样:
struct point{
int x;
int y;
}point;
结构标记和声明的变量还有花括号内成员的内容是可以用相同字符的,但感觉太乱了,除非特殊情况我一般不会用相同的声明
结构可以嵌套:
struct point{
int x;
int y;
};
struct tang{
struct point x1;
struct point x2;
};
理论来说可以做到无限嵌套。
结构的初始化
可以直接定义:
struct point m = {3,2};
初值必须是常量表达式
在表达式中可以通过结构名.成员的方式来引用特定成员:
struct point{
int x;
int y;
}p;
p.x = 1;
你甚至可以这样:
struct point{
int x;
int y;
};
struct point p ={.x = 1,.y = 2};
在嵌套结构中你可以使用如下方式引用:
struct point{
int x;
int y;
};
struct tang{
struct point x1;
struct point x2;
}m;
m.x1.x
结构的运算
在结构中你可以使用"="运算符:
struct point{
int x;
int y;
};
struct point p ={.x = 3 ,.y = 2};
struct point q = p;
这在数组中是不可行的
结构与函数
看一个程序
#include<stdio.h>
struct point{
int x;
int y;
};
struct point makep(int x,int y){
struct point sq;
sq.x = x;
sq.y = y;
return sq;
}
int main(){
struct point m = makep(5,2);
printf("%d",m.x);
}
这个程序输出结果是 5
makep函数带有两个参数返回一个结构
当然结构也可以作为参数
#include<stdio.h>
struct point{
int x;
int y;
};
struct point getstruct(struct point p){
scanf("%d",&p.x);
scanf("%d",&p.y);
return p;
}
int main(){
struct point p;
struct point m = getstruct(p);
printf("%d",m.x);
}
如果传给函数的结构很大,使用指针效率会高于复制结构的效率
那么上述程序可以改为:
#include<stdio.h>
struct point{
int x;
int y;
};
struct point getstruct(struct point *p){
scanf("%d",&(*p).x);
scanf("%d",&(*p).y);
return *p;
}
int main(){
struct point p;
struct point m = getstruct(&p);
printf("%d",m.x);
}
括号是必不可少的——因为".“的优先级高于” * “,所以*pp.x是违法的。
因为结构指针总被用到,所以C还有另一种方式,假设p是一个指针,可以用”->"来表示p指向结构成员,上面的程序又可以改为:
#include<stdio.h>
struct point{
int x;
int y;
};
struct point getstruct(struct point *p){
scanf("%d",&p->x);
scanf("%d",&p->y);
return *p;
}
int main(){
struct point p;
struct point m = getstruct(&p);
printf("%d",m.x);
}
运算符中,"->" , “.” , “( )” , "[ ]"的优先级最高,So我们可以明白比如说:
++p->x;
是加x的值.
结构数组
我们也可以声明一个结构数组来表达多个数组,例如:
#include<stdio.h>
int main(){
struct num {
char *word;
int number;
}class[10]={
{"a",1},
{"b",2},
};
printf("%s\n",class[0].word);
}
结果为
a
这表示这两个数组分别为
char *class[10]
int number[10]
类型定义(typedef)
typedef用来建立新的数据类型名,例如
typedef int Number;
这样你程序就可以用Number代表int在接下来使用
当然你可以在同学的程序里偷偷加几个typedef什么#define啥的
你也可以用某个名字去代替指针:
typedef char* string
typedef并没有创建一个新的变量类型,只是将原来的变量类型增加了一个新的名称
同理你可以用typedef给struct、enum改变类型,如:
typedef struct point{
int x;
int y;
}xy_axis;
xy_axis m;
这里的xy_axis替换了struct point。
typedef可以提高程序的可移植性和说明性,便于调整和理解。
联合
union
使一个变量可以保存多种数据类型中任何一种类型的对象,比如说:
#include<stdio.h>
int main(){
typedef union point{
char x;
int y;
}def;
def p;
printf("%lu\n",sizeof(p));
printf("%lu\n",sizeof(char));
printf("%lu\n",sizeof(int));
}
结果为
4
1
4
换一下结构声明的成员类型:
#include<stdio.h>
int main(){
typedef union point{
char *x;
int y;
}def;
def p;
printf("%lu\n",sizeof(p));
printf("%lu\n",sizeof(char*));
printf("%lu\n",sizeof(int));
}
结果为
8
8
4
将上一个与结构相对比:
#include<stdio.h>
int main(){
typedef struct point{
char *x;
int y;
}def;
def p;
printf("%lu\n",sizeof(p));
printf("%lu\n",sizeof(char*));
printf("%lu\n",sizeof(int));
}
结果为:
16
8
4
可以清楚的看到,联合所占有的空间为声明中类型空间的最大值
同时只能有一种类型:
#include<stdio.h>
int main(){
typedef union point{
char *x;
int y;
}def;
def p;
p.y = 1;
printf("%d\n",p.y);
printf("%p\n",&p.x);
printf("%p\n",&p.y);
p.x = "a";
printf("%d\n",p.y);
printf("%s\n",p.x);
printf("%p\n",&p.x);
printf("%p\n",&p.y);
}
结果为:
1
0x7ffeeb4d2a58
0x7ffeeb4d2a58
74637226
a
0x7ffeeb4d2a58
0x7ffeeb4d2a58
综上:
union读取的类型为最近的一次输入类型,union的空间为成员类型所占空间的最大值。
学习笔记,如有错误,敬请指正,谢谢