一维数组名
除了两种特殊情况外,都是指向数组第一个元素的指针
特殊情况1 sizeof 统计数组长度
特殊情况2 对数组名取地址,数组指针,步长整个数组长度
数组名是指针常量,指针的指向不可以修改的,而指针指向的值可以改
传参数时候,int arr[] 可读性更高
数组索引下标可以为负数
示例
void printArray(int arr[], int len)
{
for (size_t i = 0; i < len; i++)
{
printf("%d\n", arr[i]);
}
}
void test01()
{
int arr[5] = { 1,2,3,4,5 };
printf("%d\n", sizeof(arr));
printf("%d\n", &arr);
printf("%d\n", &arr + 1);
int len = sizeof(arr)/sizeof(arr[0]);
printArray(arr, len);
int* p = arr;
p = p + 3;
printf("%d\n", p[-1]);
printf("%d\n", *(p - 1));
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
数组指针的定义方式
先定义出数组类型,再通过类型定义数组指针变量
typedef int(ARRARY_TYPE)[5];
先定义数组指针类型,再通过类型定义数组指针变量
typedef int(*ARRARY_TYPE)[5];
直接定义数组指针变量
int(* p )[5] = &arr;
示例
void test01()
{
int arr[5] = { 1,2,3,4,5 };
typedef int(ARRARY_TYPE)[5];
ARRARY_TYPE* arrP = arr;
for (size_t i = 0; i < 5; i++)
{
printf("%d\n", (*arrP)[i]);
}
}
void test02()
{
int arr[5] = { 1,2,3,4,5 };
typedef int(*ARRARY_TYPE)[5];
ARRARY_TYPE arrP = &arr;
for (size_t i = 0; i < 5; i++)
{
printf("%d\n", (*arrP)[i]);
}
}
void test03()
{
int arr[5] = { 1,2,3,4,5 };
int(*p)[5] = &arr;
for (size_t i = 0; i < 5; i++)
{
printf("%d\n", (*p)[i]);
}
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
二维数组名
二维数组名 除了两种特殊情况外,是指向第一个一维数组的 数组指针
两种特殊情况
sizeof 统计二维数组大小
对数组名称取地址 int(*p)[3][3] = &arr
二维数组做函数参数
//void printArray(int (*array)[3], int row, int col)
//void printArray(int array[][3], int row ,int col)
//void printArray(int array[3][3], int row ,int col) 可读性比较高
数组指针 和 指针数组?
数组指针: 指向数组的指针
指针数组: 由指针组成数组
指针数组排序
选择排序
例如从小到大
开始认定最小值下标为i,从j = i+1的位置起找真实最小值下标,如果计算的真实最小值下标与i不等,互换元素

示例
void selectSort(int arr[], int len)
{
for (size_t i = 0
{
int min = i
for (size_t j = i+1
{
if (arr[min] > arr[j])
{
//更新真实最小值下标
min = j
}
}
//判断真实最小值下标是否与开始认定改的i相等,如果不等,交换匀速
if (i!=min)
{
arr[min] = arr[i] + arr[min]
arr[i] = arr[min] - arr[i]
arr[min] = arr[min] - arr[i]
}
}
}
void printArray(int arr[], int len)
{
for (size_t i = 0
{
printf("%d\n", arr[i])
}
}
void test01()
{
//从小到大,利用选择排序
int arr[] = { 2,5,1,3,4 }
int len = sizeof(arr) / sizeof(int)
selectSort(arr, len)
printArray(arr, len)
}
int main(void)
{
test01()
system("pause")
return EXIT_SUCCESS
}
利用选择排序实现 指针数组 从大到小排序
字符串对比
if ( *strcmp*(pArr[max],pArr[j]) == -1)
示例
void mySelectSort(char* pArr[], int len)
{
for (size_t i = 0; i < len; i++)
{
int max = i;
for (size_t j = i+1; j < len; j++)
{
if (strcmp(pArr[max],pArr[j])==-1)
{
max = j;
}
}
if (i !=max)
{
char* tmp = pArr[i];
pArr[i] = pArr[max];
pArr[max] = tmp;
}
}
}
void printPArr(char** pArr, int len)
{
for (size_t i = 0; i < len; i++)
{
printf("%s\n", pArr[i]);
}
}
void test02()
{
char* pArray[] = { "aaa","ccc","fff","eee","ddd","bbb" };
int len = sizeof(pArray) / sizeof(pArray[0]);
printf("len =%d\n", len);
mySelectSort(pArray, len);
printPArr(pArray, len);
}
int main(void)
{
test02();
system("pause");
return EXIT_SUCCESS;
}
结构体基本概念
加typedef 可以给结构体起别名
不加typedef ,可以直接创建一个结构体变量
结构体声明 可以是匿名
在栈上创建和在堆区创建结构体
在栈上和堆区创建结构体变量数组
示例
typedef struct Person
{
char name[64];
int age;
} myPerson;
struct Person2
{
char name[64];
int age;
} myPerson2 = {"Jim",23};
void test01()
{
struct Person p = { "tom",18 };
myPerson p1 = { "andy",18 };
printf("姓名:%s 年龄%d\n", myPerson2.name, myPerson2.age);
}
struct
{
char name[64];
int age;
} myPerson3 = {"bbb",18};
void test02()
{
printf("姓名:%s 年龄%d\n", myPerson3.name, myPerson3.age);
}
void test04()
{
struct Person p = { "aaa",10 };
struct Person* p2 = malloc(sizeof(struct Person));
strcpy(p2->name, "bbb");
p2->age = 20;
printf("姓名: %s 年龄:%d\n", p2->name, p2->age);
if (p2 != NULL)
{
free(p2);
p2 = NULL;
}
}
void printArray(struct Person personArray[], int len)
{
for (size_t i = 0; i < len; i++)
{
printf("name:%s age:%d\n", personArray[i].name, personArray[i].age);
}
}
void test05()
{
struct Person persons[] = {
{"aaa",10},{"bbb",18},{"vvvv",21}
};
int len = sizeof(persons) / sizeof(struct Person);
printArray(persons, len);
struct Person* pArray = malloc(sizeof(struct Person) * 4);
for (size_t i = 0; i < 4; i++)
{
sprintf(pArray[i].name, "name_%d", i + 1);
pArray[i].age = i + 18;
}
printArray(pArray, 4);
if (pArray != NULL)
{
free(pArray);
pArray = NULL;
}
}
int main(void)
{
test05();
system("pause");
return EXIT_SUCCESS;
}
结构体深浅拷贝
浅拷贝:逐字节拷贝
系统提供的赋值操作是 浅拷贝 – 简单值拷贝,逐字节拷贝

如果结构体中有属性 创建在堆区,就会出现问题,在释放期间,一段内存重复释放,一段内存泄露

解决方案:自己手动去做赋值操作,提供深拷贝
结构体嵌套一级指针练习
在堆区创建一个 结构体指针数组
malloc(sizeof(struct Person *) *3 )
在堆区创建出结构体变量
malloc(sizeof(struct Person))
在堆区创建出具体姓名
malloc(sizeof(char )*64);
打印数据
释放数组
示例
struct Person
{
char* name
int age
}
struct Person** allocateSpace()
{
struct Person **temp=malloc(sizeof(struct Person*) * 3)
for (size_t i = 0
{
//创建结构体内存
temp[i] = malloc(sizeof(struct Person))
//将结构体姓名 创建在堆区
temp[i]->name = malloc(sizeof(char) * 64)
//给姓名赋值
sprintf(temp[i]->name, "name_%d", i + 1)
temp[i]->age = 18 + i
}
return temp
}
void printPerson(struct Person** pArray, int len)
{
for (size_t i = 0
{
printf("name:%s age:%d\n", pArray[i]->name, pArray[i]->age)
}
}
void freeSpace(struct Person** pArray, int len)
{
if (pArray == NULL)
{
return
}
if (len<=0)
{
return
}
for (size_t i = 0
{
if (pArray[i]->name != NULL)
{
free(pArray[i]->name)
pArray[i]->name = 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
}
int main(void)
{
test01()
system("pause")
return EXIT_SUCCESS
}