1.结构体基础
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//结构体的定义
//这个定义了一个数据类型,没有分配内存。
////捆绑分配,捆绑释放
//内存四自己对齐
//用typedef重I命名
typedef struct _Teacher1 //定义结构体的第一种方法
{
char name[60];
char c;
int age;
}Teacher;
struct _Teacher //定义结构体的第二种方法
{
char name[62];
char c;
int age;
}t2,t3;
struct //定义结构体的第三种方法
{
char name[62];
char c;
int age;
}t4;
void main01()
{
//第一种方法
Teacher t1;//告诉c++编译器 分配内存 //在临时区
Teacher *p = (Teacher *)malloc(sizeof(Teacher));
//捆绑分配,捆绑释放
free(p);
//free(p->age);
//free(p->name);
system("pause");
}
void copyStruct(Teacher *to,Teacher *from)
{
*to = *from;
}
int copyStruct02(Teacher to, Teacher from)
{
to = from;
return 10;
}
void main()
{
Teacher t1;
Teacher t2;
Teacher *p = NULL;
printf(" %d \n",sizeof(Teacher)); //内存对齐 为68
p = &t1;
strcpy(t1.name,"name");
t1.age = 10;
p->age = 12;
//->的本质是寻址 寻每一个成员相对于大变量图t1的内存偏移 ,没有操作内存
printf("%d\n",t1.age);
t2 = t1; //编译器做了什么工作?
printf("%d\n",t2.age);
//C语言中,在相同类型的变量间赋值时是直接内存复制的,即将他们的内存进行复制,而两个同类型的结构体变量属于同一种变量,所以赋值时是按照他们的内存分布来直接拷贝的。
//所以,在C语言中两个相同类型的结构体变量之间是可以相互赋值的。但是要注意指针的浅层复制问题。
{
Teacher t3;
int a = 10;
//printf("t3.age: %d \n", t3.age); 未初始化,不可用
}
system("pause");
}
2.深拷贝浅拷贝
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//结构体的定义
typedef struct _AdvTeacher
{
char *name;
char buf[100];
int age;
}Teacher;
Teacher * creatT()
{
Teacher *tmp = NULL;
tmp = (Teacher *)malloc(sizeof(Teacher));
tmp->name = (char *)malloc(100);
return tmp;
}
void FreeT(Teacher *t)
{
if (t == NULL)
{
return;
}
if (t->name != NULL)
{
free(t->name);
}
}
//产生的原因
//编译器给我们提供的copy行为是一个浅copy
//当结构体成员域中含有buf的时候,没有问题
//当结构体成员域中还有指针的函数,编译器只会进行指针变量的copy。指针变量所致的内存空间,编译器不会在多分分配内存
//这就是编译器的浅copy,我们要属顺从。。。。
//
//解决方案
int copyObj(Teacher *to, Teacher *from)
{
//*to = *from;//copy;
memcpy(to, from, sizeof(Teacher));
to->name = (char *)malloc(100);
strcpy(to->name, from->name);
}
void main()
{
Teacher t1;
Teacher t2;
t1.name = (char *)malloc(100);
t1.age = 10;
//t2 = t1;//copy;
copyObj(&t2, &t1);
if (t1.name != NULL)
{
free(t1.name);
}
if (t2.name != NULL)
{
free(t2.name);
}
system("pause");
}
3.结构体高级话题
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct _A
{
int a;
};
//结构体的定义
typedef struct _AdvTeacher
{
char *name; //4
int age2;
char buf[32]; //32
int age; //4
}Teacher;
void main()
{
int i = 0;
Teacher * p = NULL;
i = (int)(&(p->age2)); //1逻辑计算在cpu中,运算
printf("i:%d \n", i);
//&属于cpu的计算,没有读写内存,所以说没有coredown
//name 为0 age2为4 相对结构体起始位置0而言的。
system("pause");
}
//-> .
void main01()
{
int i = 0;
i = (int)&(((Teacher *)0)->age);
printf("i:%d \n", i);
//&属于cpu的计算,没有读写内存,所以说没有coredown -->
system("pause");
}
4.结构体做函数参数基础
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
//结构体的定义
typedef struct _Teacher
{
char name[62];
char c;
int age;
}Teacher ;
//打印结构体
int printTArray(Teacher *tArray, int num)
{
int i = 0;
for (i=0; i<num; i++)
{
printf("%d \n", tArray[i].age);
}
return 0;
}
//
int sortTArray(Teacher *tArray, int num)
{
int i , j = 0;
Teacher tmp;
for (i=0; i<num; i++)
{
for (j=i+1; j<num; j++)
{
if (tArray[i].age > tArray[j].age)
{
tmp = tArray[i]; //编译器给我们提供的行为
tArray[i] = tArray[j];
tArray[j] = tmp;
}
}
}
return 0;
}
int getLen(int *num)
{
*num = 10;
}
//分配结构体数组内存块
//在被调用函数里面分配的内存块 传送不出来
int creatTArray(Teacher *tArray, int num)
{
tArray = (Teacher *)malloc(num * sizeof(Teacher));
if (tArray == NULL)
{
return -1;
}
return 0;
}
Teacher *creatTArray2(int num)
{
Teacher *tArray = NULL;
tArray = (Teacher *)malloc(num * sizeof(Teacher));
if (tArray == NULL)
{
return NULL;
}
return tArray;
}
//
void main01()
{
//定义一个结构体数组,给结构体数组元素赋值,给结构题排序。。。。打印
int i = 0;
int ret = 0;
Teacher tArray[3];
Teacher *pArray = NULL;
ret = creatTArray(pArray, 3);
if (ret != 0)
{
return ;
}
pArray = creatTArray2(3);
if (pArray == NULL)
{
return ;
}
for (i=0; i<3; i++)
{
printf("请键入第%d个老师的年龄:", i+1);
scanf("%d", &tArray[i].age);
}
printf("排序之前。。。。\n");
printTArray(tArray, 3);
sortTArray(tArray, 3);
printf("排序之后。。。。\n");
printTArray(tArray, 3);
system("pause");
}
void main()
{
//定义一个结构体数组,给结构体数组元素赋值,给结构题排序。。。。打印
int i = 0;
int ret = 0;
Teacher *pArray = NULL;
pArray = creatTArray2(3);
if (pArray == NULL)
{
return ;
}
for (i=0; i<3; i++)
{
printf("请键入第%d个老师的年龄:", i+1);
scanf("%d", & (pArray[i].age));
}
printf("排序之前。。。。\n");
printTArray(pArray, 3);
sortTArray(pArray, 3);
printf("排序之后。。。。\n");
printTArray(pArray, 3);
system("pause");
}
5.进阶
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
typedef struct Te1
{
char *p1;
char *p2;
char *p3;
char *p13;
char *p4;
};
//结构体的定义
typedef struct _Teacher
{
char name[64];
char *tile;
//char *p1;
//char **p2;
int age;
}Teacher ;
int printTArray(Teacher *tArray, int num)
{
int i = 0;
for (i=0; i<num; i++)
{
printf("%d %s %s \n", tArray[i].age, tArray[i].name, tArray[i].tile);
}
return 0;
}
//
int sortTArray(Teacher *tArray, int num)
{
int i , j = 0;
Teacher tmp;
for (i=0; i<num; i++)
{
for (j=i+1; j<num; j++)
{
if (tArray[i].age > tArray[j].age)
{
tmp = tArray[i]; //编译器给我们提供的行为
tArray[i] = tArray[j];
tArray[j] = tmp;
}
}
}
return 0;
}
Teacher *creatTArray2(int num)
{
int i = 0;
Teacher *tArray = NULL;
tArray = (Teacher *)malloc(num * sizeof(Teacher));
if (tArray == NULL)
{
return NULL;
}
for (i=0; i<num; i++)
{
tArray[i].tile = (char *)malloc(100);
}
return tArray;
}
void main()
{
//定义一个结构体数组,给结构体数组元素赋值,给结构题排序。。。。打印
int i = 0;
int ret = 0;
Teacher *pArray = NULL;
pArray = creatTArray2(3);
if (pArray == NULL)
{
return ;
}
for (i=0; i<3; i++)
{
printf("请键入第%d个老师的年龄:", i+1);
scanf("%d", &pArray[i].age);
printf("请键入第%d个老师的姓名:", i+1);
scanf("%s", pArray[i].name);
printf("请键入第%d个老师的职称:", i+1);
scanf("%s", pArray[i].tile);
}
printf("排序之前。。。。\n");
printTArray(pArray, 3);
sortTArray(pArray, 3);
printf("排序之后。。。。\n");
printTArray(pArray, 3);
system("pause");
}
6.结构体套二级指针
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
//结构体的定义
typedef struct _AdvTeacher
{
char name[64];
char *tile;
char **pStuArray;
//char *p1;
//char **p2;
int age;
}Teacher ;
int printTArray(Teacher *tArray, int num)
{
int i = 0, j = 0;
for (i=0; i<num; i++)
{
printf("\n老师信息为:");
printf("%d %s %s \n", tArray[i].age, tArray[i].name, tArray[i].tile);
printf("\n学生信息为:");
for (j=0; j<3; j++)
{
printf("%s ", tArray[i].pStuArray[j]);
}
}
return 0;
}
//
int sortTArray(Teacher *tArray, int num)
{
int i , j = 0;
Teacher tmp;
for (i=0; i<num; i++)
{
for (j=i+1; j<num; j++)
{
if (tArray[i].age > tArray[j].age)
{
tmp = tArray[i]; //编译器给我们提供的行为
tArray[i] = tArray[j];
tArray[j] = tmp;
}
}
}
return 0;
}
Teacher *creatTArray2(int num)
{
int i = 0, j = 0;
Teacher *tArray = NULL;
tArray = (Teacher *)malloc(num * sizeof(Teacher));
if (tArray == NULL)
{
return NULL;
}
for (i=0; i<num; i++)
{
tArray[i].tile = (char *)malloc(100);
}
//创建老师带的学生
for (i=0; i<num; i++)
{
char **ptmp = (char **)malloc((3+1)*sizeof(char *));
for (j=0; j<3; j++)
{
ptmp[j] = (char *)malloc(120);
}
//ptmp[3] = NULL;
tArray[i].pStuArray = ptmp;
}
return tArray;
}
int FreeTArray(Teacher *tArray, int num)
{
int i =0, j = 0;
if (tArray == NULL)
{
return -1;
}
for (i=0; i<num; i++)
{
char **tmp = tArray[i].pStuArray;
if (tmp ==NULL)
{
continue;;
}
for (j=0; j<3; j++)
{
if (tmp[j] != NULL)
{
free(tmp[j]);
}
}
free(tmp);
}
for (i=0; i<3; i++)
{
if (tArray[i].tile != NULL)
{
free(tArray[i].tile);
tArray[i].tile = NULL; //laji
}
}
free(tArray);
tArray = NULL; //垃圾
}
void main()
{
//定义一个结构体数组,给结构体数组元素赋值,给结构题排序。。。。打印
int i = 0, j = 0;
int ret = 0;
Teacher *pArray = NULL;
pArray = creatTArray2(3);
if (pArray == NULL)
{
return ;
}
for (i=0; i<3; i++)
{
printf("请键入第%d个老师的年龄:", i+1);
scanf("%d", &pArray[i].age);
printf("请键入第%d个老师的姓名:", i+1);
scanf("%s", pArray[i].name);
printf("请键入第%d个老师的职称:", i+1);
scanf("%s", pArray[i].tile);
printf("请键入学生信息\n");
for (j=0; j<3; j++)
{
printf("请键入第%d个学生的名字: ", j+1);
scanf("%s", pArray[i].pStuArray[j]);
}
}
printf("排序之前。。。。\n");
printTArray(pArray, 3);
sortTArray(pArray, 3);
printf("排序之后。。。。\n");
printTArray(pArray, 3);
FreeTArray(pArray, 3);
system("pause");
}
7.野指针和一级指针在一起
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//野指针产生问题分析
//指针变量和它所指内存空间变量是两个不同的概念
//解决野指针的方案
//1定义指针时 把指针变量赋值成null
//2 释放内存时,先判断指针变量是否为null
//3 释放内存完毕后,把指针变量重新赋值成null
//
void main22()
{
char *p = NULL;
p = (char *)malloc(100); //char p[100];
strcpy(p, "abcdefg");
//做业务
//此处省略5000字。。。。。
if (p != NULL)
{
free(p);
p = NULL;
}
//做业务
//此处省略5000字。。。。。
if (p != NULL)
{
free(p);
}
system("pause");
}
char *getMem2(int count)
{
char *tmp = NULL;
tmp = (char *)malloc(100 * sizeof(char)); //char tmp[100];
return tmp;
}
//实参和形参是两个不同的概念
void getMem3(int count, char *p)
{
char *tmp = NULL;
tmp = (char *)malloc(100 * sizeof(char)); //char tmp[100];
p = tmp; //在这个场景下,你给形参赋值了,没有给实参赋值
//直接修改实参没戏。。。。。。。 实参和形参是两个不同的概念
//return tmp;
}
void getMem4(int count, char **p /*out*/)
{
char *tmp = NULL;
tmp = (char *)malloc(100 * sizeof(char)); //char tmp[100];
//p = tmp; //在这个场景下,你给形参赋值了,没有给实参赋值
//直接修改实参没戏。。。。。。。 实参和形参是两个不同的概念
//间接的修改实参
*p = tmp;
//return tmp;
}
//函数调用的时候,这个场景修改不了实参
int FreeMem2(char *p)
{
if (p == NULL)
{
return -1;
}
if (p != NULL)
{
free(p);
p = NULL; //想把实参给改掉,你能修改吗? 修改不了实参。。。。。
}
return 0;
}
void main()
{
char *myp = NULL;
myp = getMem2(100);
getMem3(100, myp);
getMem4(100, &myp);
//做业务操作
//此 50000
FreeMem2(myp);
FreeMem2(myp);
}
8.第三种内存模型
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//强化指针数组char* a[30] 和 数组指针char (*a)[30]
//()[]优先级
char *a() //函数名称
{
return NULL;
}
char(*a2)(); //是一个指针变量。。。。。。分配四个自己内存
char **getMem(int count)
{
int i = 0;
char **tmp = (char **)malloc((count + 1)*sizeof(char *));
for (i = 0; i<count; i++)
{
tmp[i] = (char *)malloc(100);
}
tmp[count] = '\0'; //转义字符的0
tmp[count] = 0; //转义字符的0
tmp[count] = NULL; //转义字符的0
return tmp;
}
void sortArray(char **myArray)
{
int i = 0, j = 0;
char *tmp;
for (i = 0; myArray[i] != NULL; i++)
{
for (j = i + 1; myArray[j] != NULL; j++)
{
if (strcmp(myArray[i], myArray[j]))
{
tmp = myArray[i]; //这个地方交换的是指针变量
myArray[i] = myArray[j];
myArray[j] = tmp;
}
}
}
}
void sortArray02(char **myArray)
{
int i = 0, j = 0;
char tmp[200];
for (i = 0; myArray[i] != NULL; i++)
{
for (j = i + 1; myArray[j] != NULL; j++)
{
if (strcmp(myArray[i], myArray[j]) > 0)
{
strcpy(tmp, myArray[i]);
strcpy(myArray[i], myArray[j]);
strcpy(myArray[j], tmp); //交换是buf的内容
}
}
}
}
void printfArray(char **myArray)
{
int i = 0, j = 0;
for (i = 0; myArray[i] != NULL; i++)
{
printf("%s \n", myArray[i]);
}
}
void main01()
{
char buf[10][30] = { "dddd", "1111", "s222222", "333333", "555555555" };
printf("%s \n", *(buf + 2));
system("pause");
}
void main02()
{
char **pArray = NULL;
pArray = getMem(3);
strcpy(pArray[0], "bbbbb");
strcpy(pArray[1], "aaaa");
strcpy(pArray[2], "cccc");
printf("排序之前\n");
printfArray(pArray);
//sortArray(pArray, 3);
sortArray02(pArray);
printf("排序之后\n");
printfArray(pArray, 3);
system("pause");
}
void main()
{
//03、数组类型、数组指针类型、数组指针类型变量
typedef int MyTypeArray[5];
MyTypeArray a; //int a[5];
int intArray[3][5];
{
typedef int(*MyPTypeArray)[5];
MyPTypeArray myArrayPoint;
myArrayPoint = &a;
(*myArrayPoint)[0] = 1; //通过一个数组指针变量去操作数组内存
}
{
int(*myArrayVar)[5]; //告诉编译给我开辟4个字节的内存‘
myArrayVar = &a;
(*myArrayVar)[1] = 2;
}
{
int(*myArrayVar2)[5]; //告诉编译给我开辟4个字节的内存‘
myArrayVar2 = intArray; //
}
}
9.