Day20.C提高4

Day20.C提高4

一、一维数组

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void test01()
{
	int arr[] = { 1,2,3,4 };
	int* p = arr;
	//1.sizeof    2.对数组名取地址 &arr
	//以上两种情况下,数组名不是指向首元素的指针
	//**除了以上两种之外,数据名在其他任何情况下都是指向首元素的指针

	printf("sizeof arr:%d\n", sizeof(arr));
	printf("&arr addr:%d\n", &arr);
	printf("&arr + 1 addr:%d\n", &arr + 1);

	//数组名是一个常量指针(不可以修改)
	//arr = NULL;
	
	//数组下标可以为负数
	p += 3;
	printf("p[-1]:%d\n", p[-1]);
}

int main(void)
{
	test01();

	return 0;
}

二、如何定义一个可以指向数组的指针

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//如何定义一个可以指向数组的指针
void test02()
{
	//1.先定义数组类型,再定义数组指针类型
	typedef int(ARRAY_TYPE)[5];

	ARRAY_TYPE myarray;
	for (int i = 0; i < 5; ++i)
	{
		myarray[i] = 100 + i;
	}
	for (int i = 0; i < 5; ++i)
	{
		printf("%d ", myarray[i]);
	}

	//对数组名取地址代表指向整个数组的指针
	ARRAY_TYPE* pArray = &myarray;
	//(a).*pArray 表示拿到pArray指针指向的整个数组
	//(b).*pArray 类型就是数组名,只想首元素类型的指针

	printf("*(*pArray+1):%d\n", *(*pArray + 1));

	//2.直接定义数组指针类型
	typedef int(*ARRAY_POINTER)[5];
	ARRAY_POINTER pArr = &myarray;

	//3.直接定义数组指针变量
	int(*pArrParam)[5] = &myarray;

}

int main(void)
{
	test02();
	
	system("pause");
	return EXIT_SUCCESS;
}

三、二维数组

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void printfBiArray(int(*parr)[3], int len1, int len2)
{
	for (int i = 0; i < len1; ++i)
	{
		for (int j = 0; j < len2; ++j)
		{
			//printf("%d ", *(*(parr + i) + j));
			printf("%d ", parr[i][j]);
		}
	}
}

void test03()
{


	int arr[3][3] =
	{
		{1,2,3},
		{4,5,6},
		{7,8,9}
	};
	//int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
	//int arr[][3] = { 1,2,3,4,5,6,7,8,9 };
	
	//对于二维数组 同一维数组一样,除了sizeof ,对数组名取地址之外,数组名就是指向数组首元素的指针
	int(*pArray)[3] = arr;
	printfBiArray(arr, 3, 3);

}

int main(void)
{
	test03();

	system("pause");
	return EXIT_SUCCESS;
}

四、指针数组排序

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void test04(int* arr,int len)
{
	//定义一个最小值的指向
	int min = 0;
	for (int i = 0; i < len; ++i)
	{
		min = i;
		for (int j = i + 1; j < len; ++j)
		{
			if (arr[j] < arr[min])
			{
				//通过判断更新指向
				min = j;
			}
		}
		if (min != i)
		{
			int temp = arr[min];
			arr[min] = arr[i];
			arr[i] = temp;
		}
	}
}
//打印数组
void printfArr(int* arr, int len)
{
	for (int i = 0; i < len; ++i)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}


int main(void)
{
	int arr[] = { 5,8,9,3,4,1,2,7,6 };
	int len = sizeof(arr) / sizeof(arr[0]);
	printfArr(arr, len);
	test04(arr,len);
	printfArr(arr, len);

	system("pause");
	return EXIT_SUCCESS;
}

五、数组指针内容总结

绝大多数表达式中,数组名的值是指向数组的第一个元素的指针,这个规则只有的两个例外,sizeof和对数组名取地址(&)

指针和数组额并不相等,当我们声明一个数组的时候,同时也分配了存放数组的内存,但是声明指针的时候,只分配了容纳指针本身的空间。

当数组名作为函数参数时,实际传递给函数的是一个指向数组第一个元素的指针。

我们不但可以创建指向普通变量的指针,也可以创建指向数组的指针

六、结构体赋值

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct Person 
{
	char name[64];
	int age;
};

void test501()
{
	struct Person person1 = { "aaa",20 };
	struct Person person2 = { "bbb",30 };

	//赋值操作
	person1 = person2;

	printf("person1.name:%s person1.age:%d\n", person1.name, person1.age);
	printf("person2.name:%s person2.age:%d\n", person2.name, person2.age);

}

struct Teacher
{
	char* name;
	int age;
};

void test502()
{
	struct Teacher teacher1;
	teacher1.name = (char*)malloc(sizeof(char) * 64);
	memset(teacher1.name, 0, 64);
	strcpy(teacher1.name, "aaa");
	teacher1.age = 20;

	struct Teacher teacher2;
	teacher2.name = (char*)malloc(sizeof(char) * 128);
	memset(teacher2.name, 0, 128);
	strcpy(teacher2.name, "bbbbbbbbbbbbb");
	teacher2.age = 30;

	printf("name:%s age:%d\n", teacher1.name, teacher1.age);
	printf("name:%s age:%d\n", teacher2.name, teacher2.age);

	printf("-------------------------\n");

	//赋值操作
	//如果结构体内部有指针,并且指针指向堆空间。
	//那么如果发生赋值行为,就会产生两个问题:1、同一块内存空间被释放两次	2、内存泄漏
	//teacher1 = teacher2;
	
	//如果结构体内部有指针指向堆内存,那么就不能使用编译器默认的赋值行为,应该手动控制赋值过程。
	if (teacher1.name != NULL)
	{
		free(teacher1.name);
		teacher1.name = NULL;
	}
	teacher1.name = (char*)malloc(strlen(teacher2.name) + 1);
	memset(teacher1.name, 0, strlen(teacher2.name) + 1);
	strcpy(teacher1.name, teacher2.name);
	teacher1.age = teacher2.age;

	printf("name:%s age:%d\n", teacher1.name, teacher1.age);
	printf("name:%s age:%d\n", teacher2.name, teacher2.age);


	//释放堆内存
	if (teacher1.name != NULL)
	{
		free(teacher1.name);
		teacher1.name = NULL;
	}
	if (teacher2.name != NULL)
	{
		free(teacher2.name);
		teacher2.name = NULL;
	}



}

int main(void)
{
	//test501();
	test502();

	system("pause");
	return EXIT_SUCCESS;
}

七、结构体嵌套一级指针

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct Person
{
	char* name;
	int age;
};

//分配内存
struct Person** allocatSpace()
{
	struct Person** temp = (struct Person**)malloc(sizeof(struct Person*) * 3);
	for (int i = 0; i < 3; ++i)
	{
		temp[i] = (struct Person*)malloc(sizeof(struct Person));
		temp[i]->name = (char*)malloc(sizeof(char) * 64);
		sprintf(temp[i]->name, "name_%d", i + 1);
		temp[i]->age = 100 + i;
	}
	return temp;
}

//打印
void printfPerson(struct Person** person)
{
	for (int i = 0; i < 3; ++i)
	{
		printf("Name:%s Age:%d\n", person[i]->name, person[i]->age);
	}
}

//释放内存空间
void freeSpace(struct Person** person)
{
	if (person == NULL)
	{
		return;
	}
	for (int i = 0; i < 3; ++i)
	{
		if (person[i] == NULL)
			continue;
		if (person[i]->name != NULL)
		{
			free(person[i]->name);
			person[i]->name = NULL;
		}
		free(person[i]);
		person[i] = NULL;
	}
	free(person);
	person = NULL;
}


void test601()
{
	struct Person** person = NULL;
	person = allocatSpace();
	printfPerson(person);
	freeSpace(person);
}

int main(void)
{
	test601();


	system("pause");
	return EXIT_SUCCESS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值