结构体
(1)结构体的基本使用
#include <stdio.h>
#include <string.h>
//定义一个结构体类型
//struct是关键字
//struct Student合起来才是结构体类型
//结构体内部定义的变量不能直接赋值
//结构体只是一个类型,没有定义变量前,是没有分配空间,没有空间,就不能赋值
struct Student
{
int age;
char name[100];
int score;
};//有分号
int main()
{
//定义结构体变量
//类型名 变量名
struct Student stu;//别忘了struct关键字
//结构体变量初始化,和数组一样,要使用大括号
//只有在定义时才能初始化
struct student stu2={18,"mike",59};
//使用结构体成员,不能直接使用,需要借助结构体变量来引用
struct Student tmp;
//如果是普通变量,使用.点运算符
tmp.age=18;
//tmp.name="mike";//name成员是数组名,数组名为常量,不能修改
strcpy(tmp.name,"mike");
tmp.score=59;
//如果是指针变量,使用->
//如果是指针,指针要有合法指向,才能操作结构体成员
struct Student *p;
p=&tmp;
p->age=18;
strcpy(p->name,"mike");
p->score=59;
//然后结构体变量都可用.或->操作成员
(&tmp)->age=18;
(*p).age=18;//.的优先级比*高,所以加()
return 0;
}
(2)结构体的其他用法
#include <Stdio.h>
struct Student
{
int age;
char name[100];
int score;
}s1={18,"mike",59},s2;//表示在定义结构体的时候同时定义两个结构体变量
struct
{
int age;
char name[100];
int score;
}s3,s4;
(3)结构体数组
#include <Stdio.h>
#include <string.h>
struct Student
{
int age;
char name[50];
int score;
};
int main()
{
struct Student s;
struct Student a[5];//结构体数组
//操作元素
a[0].age=18;
strcpy(a[0].name,"mike");
a[0].score=59;
//操作某个元素地址
(a+1)->age=19;
strcpy((a+1)->name,"jiang");
(a+1)->score=60;
//操作元素
(*(a+2)).age=20;
strcpy((*(a+2)).name,"lily");
(*(a+2)).score=61;
struct Student *p=a;
p=&a[0];
p[3].age=21;
strcpy(p[3].name,"xiaoming");
p[3].score=62;
(p+4)->age=22;
strcpy((p+4)->name,"xiaoming");
(p+4)->score=88;
int i=0;
int n=sizeof(a)/sizeof(a[0]);
for(i=0;i<n;i++)
{
printf("%d,%s,%d\n",a[i].age,a[i].name,a[i].score);
}
//或
struct Student a[5]=
{
{};
{};
{};
{};
{};
};
}
(4)结构体嵌套
#include <stdio.h>
#include <string.h>
struct Info
{
int age;
char name[50];
};
struct Student
{
struct Info info;
int score;
};
int main()
{
struct Student s;
s.info.age.=18;
strcpy(s.info.name,"mike");
s.score=59;
struct Student *p=&s;
p->info.age.=18;
strcpy(p->info.name,"mike");
p->score=59;
return 0;
}
(5)同类型结构体变量赋值
#include <stdio.h>
#include <string.h>
struct Student
{
int age;
char name[50];
int score;
};
int main()
{
//相同类型的两个结构体变量可以相互赋值
//尽管两个结构体变量的内容一样,但是两个结构体是没有关系的
struct Student s1={18,"mike",59};
struct Student s2;
s2=s1;
printf("%d,%s,%d\n",s2.age,s2.name,s2.score);
}
(6)结构体值传递和地址传递区别
a.值传递
#include <stdio.h>
#icnlude <string.h>
struct Student
{
int age;
char name[50];
int score;
};
void setStu(struct Stduent tmp)
{
tmp.age=22;
strcpy(tmp.name,"jiang");
tmp.score=77;
}
int main()
{
struct Student s1={18,"mike",59};
setStu(s1);//为值传递,通过函数将是s1赋值给tmp,函数修改tmp内容,函数调用完释放tmp,不会影响到s1的值
}
b.地址传递
#include <stdio.h>
#include <string.h>
struct Student
{
int age;
char name[50];
int score;
};
void fun(struct Student *p)
{
p->age=22;
}
int main()
{
struct Student s1={18,"mike",59};
fun(&s1);
return 0;
}
(7)指针指向栈区空间
#include <Stdio.h>
#include <string.h>
struct Student
{
int age;
char name[50];
int score;
};
int main()
{
//定义一个结构体类型指针
struct Student *p;
//在栈区定义一个结构体变量
struct Student tmp;
p=&tmp;
p->age=18;
strcpy(p->name,"mike");
p->score=59;
printf("%d,%s,%d\n",p->age,p->name,p->score);
printf("%d,%s,%d\n",tmp.age,tmp.name,tmp.score);
return 0;
}
(8)指针指向堆区空间
#include <Stdio.h>
#include <string.h>
struct Student
{
int age;
char name[50];
int score;
};
int main()
{
//定义一个结构体类型指针
struct Student *p;
//指针指向堆区空间
p=(strcut Student*)malloc(sizeof(struct Student));
p->age=18;
strcpy(p->name,"mike");
p->score=59;
printf("%d,%s,%d\n",p->age,p->name,p->score);
return 0;
}
(9)成员指针指向data区或栈区
#include <Stdio.h>
#include <string.h>
struct Student
{
int age;
char *name;
int score;
};
int main()
{
struct Student s;
s.age=18;
s.name="mike";//指针变量保存字符串常量的首地址
s.score=59;
//或
struct Student s;
s.age=18;
char buf[100];
s.name=buf;
strcpy(str.name,"mike");
s.score=59;
}
(10)结构体套一级指针
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Student
{
int age;
char *name;
int score;
};
int main()
{
struct Student *p;
//需要给p分配内存
p=(struct Student*)malloc(sizeof(struct student));
if(p==NULL)
{
printf("分配失败\n");
}
p->age=18;
strcpy(p->name,"mike");
p->score=59;
return 0;
}
//无法运行,因为没有给name分配内存空间
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Student
{
int age;
char *name;
int score;
};
int main()
{
struct Student *p;
//需要给p分配内存
p=(struct Student*)malloc(sizeof(struct student));
p->name=(char *)malloc(strlen("mike")+1);
if(p==NULL)
{
printf("分配失败\n");
}
p->age=18;
strcpy(p->name,"mike");
p->score=59;
//应先释放name再释放p
if(p->name!=NUll)
{
free(p->name);
p->name=NULL;
}
if(p!=NULL)
{
free(p);
p=NULL;
}
return 0;
}
(11)共用体
#include <Stdio.h>
union Text
{
unsigned char a;
unsigned short b;
unsigned int c;
};
int main()
{
//结构体的大小可以简单认为成员大小的累加
//共用体大小为最大成员的大小
//共用体公用一块内存,所有成员的地址都一样
//给某个成员赋值会影响到另外的成员
//左边是高位,右边是低位
//高位放高地址,低位放低地址
return 0;
}
(12)枚举的使用
#include <Stdio.h>
#define pink 0;
#define red 1;
#define green 2;
#define white 3;
#define blue 4;
#define yellow 5;
//或
//enum是关键字
//里面的成员是一个标识符,枚举常量
//第一个成员如果没有赋值,默认为0,下一个成员比上一个多1
//枚举类型
//成员:枚举成员(枚举常量)
enum Color
{
pink,red,greed,white,blue,yellow
};
int main()
{
int flag=1;
if(flag==red)
{
printf("red\n");
}
//枚举变量flag2
enum Color flag2;
//可以使用枚举成员给发flag2赋值
flag2=pink;//等价于pink=0
//也可以使用常量给flag2赋值,不推荐
flag2=pink;//
}
(13)typedef的使用
#include <stdio.h>
//给struct Text2类型起一个别名叫Text2
typedef struct Text2
{
int a;
}Text2;
Text2 tmp;
int main()
{
//tepedef给一个以存在的类型起一个别名
//typedef不能创建新类型
//给int起一个别名叫int64
typedef int int64;//有分号
int64 a;//等价于int a;
//宏定义是发生在预处理
//typedef是在编译阶段
}
n");
}
//枚举变量flag2
enum Color flag2;
//可以使用枚举成员给发flag2赋值
flag2=pink;//等价于pink=0
//也可以使用常量给flag2赋值,不推荐
flag2=pink;//
}
(13)typedef的使用
#include <stdio.h>
//给struct Text2类型起一个别名叫Text2
typedef struct Text2
{
int a;
}Text2;
Text2 tmp;
int main()
{
//tepedef给一个以存在的类型起一个别名
//typedef不能创建新类型
//给int起一个别名叫int64
typedef int int64;//有分号
int64 a;//等价于int a;
//宏定义是发生在预处理
//typedef是在编译阶段
}