结构体_结构体指针,typedef
结构体定义
#define _CRT_SECURE_NO_WARNINGS
#include #include #include #include //上面的头文件 下面几个例子都要有
//结构体 关键字 struct
//结构体是一种构造数据类型
//把不同的数据类型整合起来成为一个自定义的数据类型
struct Man{
//成员
char name[20];
int age;
//int (*func)();//也可以是函数指针
};
void main(){
//1.初始方式第一种
//struct Man m1 = { "name", 26 };
//2.初始方式 第二种
struct Man m1;
m1.age = 26;
//m2.name = "struct_name";//这样会报错 前面说过字符串初始化的方式 这里有两种方式 1 改变结构体的name为指针 2 使用拷贝函数
strcpy(m1.name, "cpy_name");
sprintf(m1.name, "sprintf_name");//这两种方式都可以 赋值
printf("%s,%d\n", m1.name, m1.age);
//struct 可以相互赋值
struct Man m2 = m1;
printf("%s,%d\n", m2.name, m2.age);
getchar();
}
效果图
01:
结构体的写法
//结构体的写法
struct Man{
//成员
char name[20];
int age;
}m1, m2 = { "jack", 20 };
void main(){
strcpy(m1.name, "m1name");
m1.age = 10;
printf("%s,%d\n", m2.name, m2.age);
//printf("%s,%d\n", m1.name, m1.age);
getchar();
}
效果图
01:
匿名结构体
//匿名结构体
struct {
char name[20];
int age;
}m1;
结构体嵌套
//结构体嵌套
struct teacher
{
char name[20];
};
struct student{
char name[20];
int age;
struct teacher t;
};
void main(){
//如何进行赋值 字面量的方式
//struct student s1 = { "jack", 21, {"name"} };
//或者
struct student s1;
s1.age = 10;
//s1.t.name = "liu";//需要使用拷贝函数
strcpy(s1.name, "student_name");
strcpy(s1.t.name, "lml");
printf("%s,%d,%s\n", s1.name, s1.age, s1.t.name);
system("pause");
}
01:
还可以这样写
//还可以这样写
struct Student{
char name[20];
int age;
struct Teacher{
char name[20];
}t;
};
void main(){
struct Student s1;
strcpy(s1.t.name, "lml");//和上面一样的效果
system("pause");
}
结构体指针
结构体指针1
struct Man{
char name[20];
int age;
};
void main(){
struct Man m1 = { "name", 30 };
//结构体指针
struct Man *p = &m1;
printf("%s,%d\n", m1.name, m1.age);
printf("%s,%d\n", (*p).name, (*p).age);
//->箭头 是(*p)简写形式
printf("%s,%d\n", p->name, p->age);
system("pause");
}
结构体指针2
指针与结构体数组
struct Man{
char name[20];
int age;
};
void main(){
struct Man mans[] = { { "jack", 20 }, { "rose", 19 } };
//遍历数组 两种方式
//1
struct Man *p = mans;
for (; p < mans + 2; p++){
printf("%s,%d\n", p->name, p->age);
}
//2
int i = 0;
for (; i < sizeof(mans) / sizeof(struct Man); i++){
printf("%s,%d\n", mans[i].name, mans[i].age);
}
system("pause");
}
结构体的大小
//结构体变量的大小,必须是最宽基本数据类型的整数倍 (16/8 16/4 都能整除 )
//提升读取的效率
struct Man
{
int age;//4字节
double weight;//8字节
};
void main(){
struct Man m1 = {20,89.0};
printf("%#x,%d\n",&m1,sizeof(m1));
getchar();
}
可以看到 打印出来是16个字节 怎么算出来的? age 4字节 weight 8字节 那么 16 都能整除 时间换空间 空间换时间
结构体与动态内存分配
struct Man{
char *name;
int age;
};
void main(){
struct Man *m_p = (struct Man*)malloc(sizeof(struct Man) * 10);
struct Man *p = m_p;//这样赋值的话就不会改变 *m_p
//赋值
p->name = "jack";
p->age = 20;
p++;//下一个
p->name = "rose";
p->age = 18;
struct Man *loop_p = m_p;
for (; loop_p < m_p + 2; loop_p++)
{
printf("%s,%d\n", loop_p->name, loop_p->age);
}
free(m_p);//用完释放
getchar();
}
运行结果
结构体取别名
//typedef 类型取别名
//1.不同名称代表在干不同的事情typedef int jint;
//2.不同情况下,使用不同的别名
//#if defined(__cplusplus)
//typedef _JNIEnv JNIEnv;
//typedef _JavaVM JavaVM;
//3.书写简洁
struct Man{
char name[20];
int age;
};
typedef struct Man JavaMan;
typedef struct Man* JM;//取别名
//Age 就是 int类型的别名
typedef int Age;
//Ap 就是 int类型指针的别名
typedef int* Ap;
//简写
typedef struct Woman{
char name[20];
int age;
}W,*Wp;//W 是woman结构体的别名, WP 是woman结构体指针的别名
void main(){
int i = 5;
Ap p = &i;//这里AP 就是int 类型指针的别名
//结构体变量
W w1 = { "rose", 20 };
//结构体指针
Wp wp1 = &w1;
printf("%s,%d\n", w1.name, w1.age);
printf("%s,%d\n", wp1->name, wp1->age);
system("pause");
}
运行结果
结构体函数指针成员
//结构体函数指针成员
struct Girl{
char *name;
int age;
//函数指针
void(*sayHi)(char*);
};
//Girl结构体类似于Java中的类,name和age类似于属性,sayHi类似于方法
void sayHi(char* text){
MessageBoxA(0, text, "titel", 0);//弹框
}
void main(){
struct Girl g1;
g1.age = 19;
g1.name = "Lucy";
g1.sayHi = sayHi;
sayHi("nihao");
system("pause");
}
运行结果
–下面一个是上面的变种
还是结构体函数指针 增加了一个方法
typedef struct Girl{
char *name;
int age;
//函数指针
void(*sayHi)(char*);
}Girl;
//Girl结构体指针取别名GirlP
typedef Girl* GirlP;
void sayHi(char* text){
MessageBoxA(0, text, "title", 0);
}
//通过传递指针改名
void MyRename(Girl* gp1, char* text){
printf("%s,%d\n", gp1->name, gp1->age);
gp1->name = text;
}
void main(){
Girl g1 = { "Lucy", 18, sayHi };
printf("%s,%d\n", g1.name,g1.age);
GirlP gp1 = &g1;
gp1->sayHi("firstName");
//传递指针改名
MyRename(gp1, "newname");
printf("gp1 = %s,%d\n", gp1->name, gp1->age);
if (NULL != gp1){
gp1 = NULL;
free(gp1);
}
system("pause");
}
这里 有个坑啊 我一开始 想使用rename 这个方法 但是c里面库里面已经有这个 方法了
导致我这里一直报错 找不到原因 改成Myrename 就好了 下面放一下结果图