#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include"stdlib.h"
#include"string.h"
//自己创建一个数据类型: 数据类型的本质是固定大小内存块的别名//里面的数据类型 类型是 结构体
//.c CP注意结构体定义变量的时候,c和C++编译器的处理行为不一样
//结构体类型typedef
//结构体变量类型放4个字节存放;
typedef struct Teacher
{
char name[62];
int age;
}Teacher;
//第二种定义接头类型在后面直接加上变量
/*
struct
{
} t1,t2;
*/
//形参改变
void copyone(Teacher from, Teacher to)
{
memcpy(&to, &from, sizeof(Teacher));
}
//地址改变;
void copytwo(Teacher *from, Teacher *to)
{
memcpy(to, from, sizeof(Teacher));
}
//两个结构体变量之间可以copy数据,这个是C编译器给我提供的行为,我们要顺从
void main1()
{
//告诉编译器要分配内存;
//第一种定义结构体变量
Teacher t1 = { "dddd", 40 }; //赋值方法 第一种; struct Teacher t1={"ddd",40};
//第二种直接数据类型后面加变量
Teacher t2;
t2 = t1;//这是赋值号,不是初始化;
Teacher *p = NULL;
p = &t2;
printf("sizeof(t1):%d\n", sizeof(t1));
printf("t2.name:%s\n", t2.name);
//用memcpy函数完成两个结构体变量之间的copy
memcpy(&t2, &t1, sizeof(struct Teacher)); //把t1里面的按照字符串的方式copy给t2 copy sizeof(struct teacher)个字节
printf("p->name:%s %d\n", p->name, p->age); //用箭头; 指向结构体的用箭头
printf("t1.name:%s\n", t1.name);//结构体内部用.
printf("\n\n\n");
//调用函数赋值;
copyone(t1, t2);
system("pause");
}
//第二种调用函数来赋值。手工赋值;
void main2()
{
Teacher t1 = { "dddd", 40 };
Teacher t2 = { "t2", 50 };
Teacher *p = NULL;
//结构体类型是复杂类型,结构体指针出来就是一级指针
printf("%x", t1); //数据类型名称相当于首地址;相当于一级指针。
printf("\n%x\n", &t1);
// 第一种 调用函数赋值(函数里面为形参)
copyone(t1, t2);
printf("%s\n", t2.name); //值没有改变,调用的函数为形参;
printf("%s\n", p->name); //值为null 拷贝,形参
printf("\n\n");
//第二种调用函数,指针函数
copytwo(&t1, &t2);
printf("%s\n", t2.name);//指针改变地址的
printf("%s\n", p->name);
system("pause");
}
//memset函数解释 函数拷贝ch 到buffer 从头开始的count 个字符里, 并返回buffer指针。
//memset() 可以应用在将一段内存初始化为某个值
void creatTarry(Teacher *p, int count)
{
int i = 0;
Teacher *p1 = (Teacher *)malloc(count*sizeof(Teacher));
if (p1 == NULL)
{
return;
}
for (i = 0; i < count; i++)
{
memset(&p1[i], 0, sizeof(Teacher));
memset(p1 + i, 0, sizeof(Teacher)); // 或者 这样子写。p1是内存的首地址+i就是步长加一个就到了下一个内存地址了
}
p = p1;
}
void main4()
{
Teacher tArray[10];
Teacher *pa = NULL;
tArray[0].age = 10;
creatTarry(pa, 2);
tArray[0].age = 10;
system("pause");
}
//避免野指针
void main5()
{
//声明指针变量的时候null
char *p = NULL;
p = (char *)malloc(100);
//
if (p != NULL)
{
free(p);
p = NULL;
}
//为什么下面要继续释放,为了防止忘记啊;
//业务模型复杂了
//次数省略一万行
if (p != NULL)
{
free(p);
p = NULL;
}
}
//2个结构体变量之间的copy行为 ★
//输出
void printffArray(Teacher *pArray, int coutn)
{
int i = 0;
for (i = 0; i < 4; i++)
{
printf("请输入age : ");
printf("%d\n", pArray[i].age);
}
}
//排序
void sorttArray(Teacher *pArray, int coutn)
{
int i = 0, j = 0;
Teacher temp; //数据结构里面内容排序如果需要临时变量的话。这个临时变量也要是 这个数据类型;
for (i = 0; i < 4; i++)
{
for (j = i + i; j < coutn; j++)
{
if ((pArray[i].age) < (pArray[j].age))
{
temp.age = pArray[i].age;
pArray[i].age = pArray[j].age;
pArray[j].age = temp.age;
}
}
//如果加上下面这句话,等于就是排序完成打印出来了。
// printf("%d\n", pArray[i].age);
}
}
void main6()
{
int i = 0;
Teacher tArray[10];
for (i = 0; i < 4; i++)
{
printf("\n请输入age:");
scanf_s("%d", &tArray[i].age);
}
//排序之前;
printffArray(tArray, i);
//排序
sorttArray(tArray, i);
printf("\n");
//排序之后
printffArray(tArray, i);
system("pause");
}
//memset函数解释 函数拷贝ch 到buffer 从头开始的count 个字符里, 并返回buffer指针。
//memset() 可以应用在将一段内存初始化为某个值
Teacher *creatTArray(int count)
{
int i = 0;
Teacher *p1 = (Teacher *)malloc(count*sizeof(Teacher));
if (p1 == NULL)
{
return NULL;
}
for (i = 0; i < count; i++)
{
memset(&p1[i], 0, sizeof(Teacher));
// memset(p1+i, 0, sizeof(Teacher));//第二种方法
}
return p1;
}
void FreeTarry(Teacher *tArray, int count)
{
int i = 0;
if (tArray != NULL)
{
free(tArray);
tArray = NULL;//垃圾话语
}
}
void main()
{
int i = 0;
Teacher *pArray = creatTArray(4);
if (pArray == NULL)
{
return;
}
for (i = 0; i < 4; i++)
{
int tmp = 0;
printf("\n请输入age: ");
scanf("%d", &(pArray[i].age));
}
printf("\nsorted before\n");
printffArray(pArray, 4);
printf("\nsorted after\n");
sorttArray(pArray, 4);
printffArray(pArray, 4);
FreeTarry(pArray, 4);
system("pause");
}
自己建立一个结构体类型,里面有结构体的浅拷贝以及赋值;调用函数排序,void main5避免野指针
最新推荐文章于 2023-10-18 00:18:48 发布