定义结构体变量
struct Student{
char *name;
int age;
int score;
};
void main()
{
struct Student st1;
system("pause");
}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct Student{
char *name;
int age;
int score;
}student;
void main()
{
student st1;
system("pause");
}
struct Student{
char *name;
int age;
int score;
}st2;
void main()
{
system("pause");
}
struct {
char *name;
int age;
int score;
}st2;
初始化变量
//方法一
typedef struct Teacher
{
char name[64];
int age ;
int id;
}Teacher;
Teacher t3 = {"aaaa", 31, 01};
//方法二
struct Student2
{
char name[64];
int aga ;
}s5 = {"names", 21};
//方法三
struct
{
char name[64];
int aga ;
}s6 = {"names", 21};
访问成员
使用.运算符访问结构体成员
使用->运算符访问结构体成员
在定义了 library 和 library2 两个结构体后,若想要访问其内部成员,应该使用结构体成员运算符点(.)就可以,例如:
library.value = 9;
library.title
如何使用结构体指针访问结构体成员
1、结构体指针的定义和初始化
struct book *it;
it = &library;
2、使用结构体指针it访问结构体成员变量
it->value = 9;
it->title;
结构体变量作函数参数 VS 结构体指针作函数参数
void copyTeacher(Teacher to, Teacher from )
{
to = from;
}
//值传递
void copyTeacher02(Teacher *to, Teacher *from )
{
//(*to) = (*from);
*to = *from;
}
void main()
{
Teacher t1 = {"aaaa", 32, 02};
Teacher t2;
Teacher t3;
memset(&t3, 0, sizeof(t3));
t2 = t1; //=号操作下 编译器的行为
//编译器给我们提供 简单 =号 赋值操作 。。。我们要顺从
printf("t2.name:%s \n", t2.name);
printf("t2.age:%d \n", t2.age);
copyTeacher(t3, t1);
printf("copyTeacher() after \n");
printf("t3.name:%s \n", t3.name);
printf("t3.age:%d \n", t3.age);
printf("hello...\n");
copyTeacher02(&t3, &t1);
printf("copyTeacher02() after \n");
printf("t3.name:%s \n", t3.name);
printf("t3.age:%d \n", t3.age);
printf("hello...\n");
system("pause");
return ;
}
t2.name:aaaa
t2.age:32
copyTeacher() after
t3.name:
t3.age:0
hello...
copyTeacher02() after
t3.name:aaaa
t3.age:32
hello...
请按任意键继续. . .
结构体指针的输入输出模型
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct Teacher
{
char name[64];
int age ;
int id;
}Teacher;
void printTeacher(Teacher *array, int num)
{
int i = 0;
for (i=0; i<num; i++)
{
printf("age:%d \n", array[i].age);
}
}
void sortTeacer(Teacher *array, int num)
{
int i,j;
Teacher tmp;
for (i=0; i<num; i++)
{
for (j=i+1; j<num; j++)
{
if (array[i].age > array[j].age)
{
tmp = array[i]; //=号操作 赋值操作
array[i] = array[j];
array[j] = tmp;
}
}
}
}
// 结构体数组 3 输入老师的年龄,排序
void main()
{
int i = 0;
Teacher Array[3]; //在stack 分配内存
int num = 3;
for (i=0; i<num; i++)
{
printf("\nplease enter age:");
scanf("%d", &(Array[i].age) );
}
//打印老师年龄
// for (i=0; i<num; i++)
// {
// printf("age:%d \n", Array[i].age);
// }
printTeacher(Array, num);
sortTeacer(Array, num);
printf("排序之后\n");
printTeacher(Array, num);
printf("hello...\n");
system("pause");
return ;
}
Teacher * createTeacher(int num)
{
Teacher * tmp = NULL;
tmp = (Teacher *)malloc(sizeof(Teacher) * num); // Teacher Array[3]
if (tmp == NULL)
{
return NULL;
}
return tmp; //
}
void FreeTeacher(Teacher *p)
{
if (p != NULL)
{
free(p);
}
}
void main233()
{
int i = 0;
//Teacher Array[3]; //在stack 分配内存
int num = 3;
Teacher *pArray = NULL;
pArray = createTeacher(num);
for (i=0; i<num; i++)
{
printf("\nplease enter age:");
scanf("%d", & (pArray[i].age) );
}
//打印老师年龄
// for (i=0; i<num; i++)
// {
// printf("age:%d \n", Array[i].age);
// }
printTeacher(pArray, num);
sortTeacer(pArray, num);
printf("排序之后\n");
printTeacher(pArray, num);
FreeTeacher(pArray);
printf("hello...\n");
system("pause");
return ;
}
高级一点的输出模型
int createTeacher02(Teacher **pT, int num)
就是把简单输出模型的返回值改为int类型,将在堆空间分配的内存从函数参数用二级指针甩出来。
//修改如下
int createTeacher222(Teacher **pT, int num)
{
Teacher * tmp = NULL;
tmp = (Teacher *)malloc(sizeof(Teacher) * num); // Teacher Array[3]
if (tmp == NULL)
{
return NULL;
}
*pT = tmp;
return 0; //
}
void main()
{
int i = 0;
//Teacher Array[3]; //在stack 分配内存
int num = 3;
Teacher *pArray = NULL;
createTeacher222(&pArray,num);
for (i = 0; i<num; i++)
{
printf("\nplease enter age:");
scanf("%d", &(pArray[i].age));
}
printTeacher(pArray, num);
sortTeacer(pArray, num);
printf("排序之后\n");
printTeacher(pArray, num);
FreeTeacher(pArray);
printf("hello...\n");
system("pause");
return;
}
结构体中套一级指针
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct _student{
char name[64];
char *alias;
int age;
}student;
int createStudent(student **ptr,int count)
{
int ret = 0;
int i = 0;
student * tmp = NULL;
tmp = (student*)malloc(count*sizeof(student));//申请结构体变量所需的内存空间,相当于一个结构体数组
if (tmp == NULL)//申请失败
{
return -1;
}
memset(tmp, 0, count*sizeof(student));//初始化新分配到的内存空间
for (i = 0; i < count;i++){//逐个对结构体变量中的一级指针成员申请空间,否则之前申请的空间只是一个指针变量,这个指针变量并没有实际的内存空间
tmp[i].alias = (char *)malloc(64);
if (NULL == tmp[i].alias){
return -1;
}
}
*ptr = tmp;//通过函数参数甩出内存空间
return ret;
}
int freeStudent(student **ptr,int count)
{
int ret = 0;
int i = 0;
student * tmp = NULL;
if (ptr == NULL){
return -1;
}
tmp = *ptr;
for (i = 0; i < count; i++)
{
if (tmp[i].alias != NULL){
free(tmp[i].alias);
tmp[i].alias = NULL;
}
}
free(tmp);
*ptr = NULL;
return ret;
}
void printStudent(student *ptr, int count)
{
int i = 0;
for (i = 0; i < count; i++){//逐个打印结构体变量的age成员
printf("age:%d\n", ptr[i].age);
}
}
//依据年龄排序
void sortStudent(student *ptr, int count)
{
int i = 0, j = 0;
student tmp;
for (i = 0; i < count;i++)
{
for (j = i + 1; j < count; j++)
{
if (ptr[i].age > ptr[j].age)
{
tmp = ptr[i];
ptr[i] = ptr[j];
ptr[j] = tmp;
}
}
}
}
int main()
{
int ret = 0;
student *pStudent = NULL;
int num = 3,i = 0;
ret = createStudent(&pStudent, num);//创造一个结构体数组
if (-1 == ret){
return -1;
}
for (i = 0; i < num; i++)//依次输入结构体成员变量的值
{
printf("\nplease enter age:");
scanf("%d", &(pStudent[i].age));
printf("\nplease enter name:");
scanf("%s", pStudent[i].name); //向指针所指的内存空间copy数据
printf("\nplease enter alias:");
scanf("%s", pStudent[i].alias); //向指针所指的内存空间copy数据
}
printf("排序之前\n");
printStudent(pStudent, num);
sortStudent(pStudent, num);
printf("排序之后\n");
printStudent(pStudent, num);
freeStudent(&pStudent,num);
system("pause");
return ret;
}
结构体中套二级指针
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define FRIEND_NUM 3
typedef struct _student{
char name[64];
char *alias;
char **friends;
int age;
}student;
int createStudent(student **ptr,int count)
{
int ret = 0;
int i = 0, j = 0;
student * tmp = NULL;
char **ptmp = NULL;
tmp = (student*)malloc(count*sizeof(student));//申请结构体变量所需的内存空间,相当于一个结构体数组
if (tmp == NULL)//申请失败
{
return -1;
}
memset(tmp, 0, count*sizeof(student));//初始化新分配到的内存空间
for (i = 0; i < count;i++){//逐个对结构体变量中的一级指针成员申请空间,否则之前申请的空间只是一个指针变量,这个指针变量并没有实际的内存空间
/*一级指针内存模型*/
tmp[i].alias = (char *)malloc(64);
if (NULL == tmp[i].alias){
return -1;
}
/*二级指针第三种内存模型*/
ptmp = (char**)malloc(FRIEND_NUM*sizeof(char*));//二级指针指向一个二维数组,第一维是char*
if (ptmp == NULL)
{
return -1;
}
for (j = 0; j < FRIEND_NUM; j++)
{
ptmp[j] = (char*)malloc(64);//第一维的每一个char*指向一个malloc空间
}
tmp[i].friends = ptmp;//将二级指针抛出给已分配好的结构体二级指针成员变量
}
*ptr = tmp;//通过函数参数甩出内存空间
return ret;
}
int freeStudent(student **ptr,int count)
{
int ret = 0;
int i = 0,j = 0;
char ** ptmp = NULL;
student * tmp = NULL;
if (ptr == NULL){
return -1;
}
tmp = *ptr;
for (i = 0; i < count; i++)
{
if (tmp[i].alias != NULL){//释放一级指针
free(tmp[i].alias);
tmp[i].alias = NULL;
}
if (tmp[i].friends != NULL)//释放二级指针
{
ptmp = tmp[i].friends;
for (j = 0; j < FRIEND_NUM; j++)
{
if (ptmp[j] != NULL)
{
free(ptmp[j]);
ptmp[j] = NULL;
}
}
free(ptmp);
tmp[i].friends = NULL;//注意ptmp只是一个临时变量,不能修改原结构体成员的值
}
}
free(tmp);
*ptr = NULL;//修改主调函数的一级指针要使用二级指针
return ret;
}
void printStudent(student *ptr, int count)
{
int i = 0;
for (i = 0; i < count; i++){//逐个打印结构体变量的age成员
printf("age:%d\n", ptr[i].age);
}
}
//依据年龄排序
void sortStudent(student *ptr, int count)
{
int i = 0, j = 0;
student tmp;
for (i = 0; i < count;i++)
{
for (j = i + 1; j < count; j++)
{
if (ptr[i].age > ptr[j].age)
{
tmp = ptr[i];
ptr[i] = ptr[j];
ptr[j] = tmp;
}
}
}
}
int main()
{
int ret = 0;
student *pStudent = NULL;
int num = 3,i = 0,j = 0;
ret = createStudent(&pStudent, num);//创造一个结构体数组
if (-1 == ret){
return -1;
}
for (i = 0; i < num; i++)//依次输入结构体成员变量的值
{
printf("\nplease enter age:");
scanf("%d", &(pStudent[i].age));
//printf("\nplease enter name:");
//scanf("%s", pStudent[i].name); //向指针所指的内存空间copy数据
//printf("\nplease enter alias:");
//scanf("%s", pStudent[i].alias); //向指针所指的内存空间copy数据
for (j = 0; j < FRIEND_NUM; j++)//给二级指针指向的内存空间的一级指针指向的内存空间赋值
{
printf("please enter student name:");
scanf("%s", pStudent[i].friends[j]);
}
}
printf("排序之前\n");
printStudent(pStudent, num);
sortStudent(pStudent, num);
printf("排序之后\n");
printStudent(pStudent, num);
freeStudent(&pStudent,num);
system("pause");
return ret;
}
结构体的深浅拷贝
编译器的等号操作只会把指针变量的值拷贝,不会把指针变量指向的内存空间拷贝过去,就是所谓的浅拷贝(只进行简单的值拷贝操作)。
memcpy函数也是浅拷贝
结构体里面出现一级或者二级指针会出现浅拷贝
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct __teacher
{
char name[64];
int age;
char *alias;
}Teacher;
void copyTeacher(Teacher *to,Teacher *from)
{
//*to = *from;//浅拷贝
memcpy(to, from, sizeof(Teacher));//浅拷贝
}
int main(void)
{
Teacher t1;
Teacher t2;
strcpy(t1.name,"name1");
t1.alias = (char*)malloc(100);
strcpy(t1.alias,"ssss");
copyTeacher(&t2, &t1);
if (t1.alias != NULL)
{
free(t1.alias);
t1.alias = NULL;
}
if (t2.alias != NULL)//运行到这里由于前面已经free,这里二次free会出错
{
free(t2.alias);
t2.alias = NULL;
}
system("PAUSE");
return 1;
}
//要进行深拷贝只能是显示的分配内存,即在堆里面再开辟一块内存给另一个结构体的指针成员使用,所以可以进行二次释放。主要代码如下:
void copyTeacher(Teacher *to,Teacher *from)
{
*to = *from;
to->alias = (char *)malloc(100);
strcpy(to->alias,from->alias);
//memcpy(to, from, sizeof(Teacher));
}