并非从0开始的c++ day7
指针数组排序
这里使用选择排序
selectSort2(char* pArr[], int len)
{
int max;
for (int i = 0; i < len; i++)
{
max = i;
for (int j = i; j < len; j++)
{
if (strcmp(pArr[max], pArr[j]) == -1)
{
max = j;
}
}
if (max != i)
{
char* temp = pArr[max];
pArr[max] = pArr[i];
pArr[i] = temp;
}
}
}
void printpArr(char *pArr[],int len)
{
for (int i = 0; i < len; i++)
{
printf("%s\n", pArr[i]);
}
}
void test02()
{
char* pArr[] = { "aaa","bbb","ccc","ddd","fff","eee" };
//经过排序形成fff eee ddd ccc bbb aaa降序排序,利用选择排序算法
int len = sizeof(pArr) / sizeof(char*);
selectSort2(pArr, len);
printpArr(pArr, len);
}
使用strcmp来对比指针
结构体
结构体使用
结构体的三种定义方式
1
typedef struct Person
{
char name[64];
int age;
}myPerson;//这里的是别名
void test01()
{
myPerson p1 = { "aaa",18 };
}
2
//第二种定义方式
struct Person2
{
char name[64];
int age;
}myPerson2 = {"bbb",10}; //myPerson2是结构体变量
void test02()
{
myPerson2.age = "aaa";
strcpy(myPerson2.name, "aaaaa");
}
3
//第三种定义
struct
{
char name[64];
int age;
}myPerson3 = {"xxxx",10}; //匿名的 结构体变量
void test03()
{
strcpy(myPerson3.name, "zzzz");
myPerson3.age = 100;
}
结构体分配内存
//结构体分配内存
void test04()
{
//在栈上
struct Person p1 = { "张三",18 };
//在堆区
struct Person * p2 = malloc(sizeof(struct Person));
strcpy(p2->name, "李四");
p2->age = 19;
free(p2);
}
结构体变量数组
void printPerson(struct Person arr[], int len)
{
for (int i = 0; i < len; i++)
{
printf("姓名:%s 年龄:%d\n", arr[i].name, arr[i].age);
}
}
//结构体变量数组
void test05()
{
//在栈上分配
struct Person personArray[] =
{
{"aaaa",10},
{"bb",20},
{"ccccc",30},
{"ddd",40},
};
int len = sizeof(personArray) / sizeof(struct Person);
printPerson(personArray, len);
//在堆区分配
struct Person* pArray = malloc(sizeof(struct Person) * 4);
for (int i = 0;i < 4;i++)
{
sprintf(pArray[i].name, "name_%d", i + 1);
pArray[i].age = i + 18;
}
printPerson(pArray, 4);
if (pArray != NULL)
{
free(pArray);
pArray = NULL;
}
}
结构体赋值问题
对比学习
struct Person
{
char name[64];
int age;
};
void test01()
{
struct Person p1 = { "Tom",18 };
struct Person p2 = { "Jerr",19 };
p1 = p2;
printf("p1姓名 : %s 年龄:%d\n", p1.name, p1.age);
printf("p2姓名 : %s 年龄:%d\n", p2.name, p2.age);
}
与下面代码对比
struct Person2
{
char* name;
int age;
};
void test02()
{
struct Person2 p1;
p1.name = malloc(sizeof(char) * 64);
strcpy(p1.name, "Tom");
p1.age = 18;
struct Person2 p2;
p2.name = malloc(sizeof(char) * 128);
strcpy(p2.name, "Jerry");
p2.age = 19;
printf("p1姓名 : %s 年龄:%d\n", p1.name, p1.age);
printf("p2姓名 : %s 年龄:%d\n", p2.name, p2.age);
if (p1.name != NULL)
{
free(p1.name);
p1.name = NULL;
}
if (p2.name != NULL)
{
free(p2.name);
p2.name = NULL;
}
}
下面代码若在free前,令p1 = p2;,则会报错
因为逐字节拷贝 = 浅拷贝 ,由于浅拷贝
导致:堆区p2的数据重复释放,这个原因报的错
改错:重新在堆区开辟一块足够大的内存来复制p2的内容,这样在释放时,两个指针指向不同的区域,就不会报错
也就是手动赋值行为解决问题
这个方法称为深拷贝,代码如下
//手动赋值
//释放原来堆区内存
if (p1.name != NULL)
{
free(p1.name);
p1.name = NULL;
}
//分配内存
p1.name = malloc(strlen(p2.name) + 1);//+1是为了拿\0
strcpy(p1.name, p2.name);
p1.age = p2.age;
/// //
结构体嵌套一级指针练习
主调函数中若没有分配内存,被调函数需要传入高级指针才能分配内存
思路:
//结构体设计
struct Person
{
char* name;//姓名
int age;//年龄
};
struct Person** allocateSpace()
{
struct Person ** temp = malloc(sizeof(struct Person*) * 3);
for (int i = 0; i < 3; i++)
{
//给每个Person分配内存
temp[i] = malloc(sizeof(struct Person));
//给每个Person的name分配内存空间
temp[i]->name = malloc(sizeof(char) * 64);
//给name姓名赋值
sprintf(temp[i]->name, "name_%d", i+1);
temp[i]->age = i + 20;
}
return temp;
}
//打印人员信息
void printPerson(struct Person ** array,int len)
{
for (int i = 0; i < len; i++)
{
printf("姓名:%s 年龄:%d\n", array[i]->name, array[i]->age);
}
}
void freeSpace(struct Person** pArray, int len)
{
if (pArray == NULL || len <= 0)
{
return;
}
for (int i = 0; i < len; i++)
{
if (pArray[i]->name != NULL)
{
//释放人名
free(pArray[i]->name);
pArray[i]->name = NULL;
}
//释放人
if (pArray[i] != NULL)
{
free(pArray[i]);
pArray[i] = NULL;
}
}
free(pArray);
pArray = NULL;
}
void test01()
{
struct Person** pArray = NULL;
pArray = allocateSpace();
//打印输出入的信息
printPerson(pArray, 3);
//释放堆区数据
freeSpace(pArray,3);
pArray = NULL;
}