Day 12 指针函数, 数组的指针

本文深入探讨了C语言中的指针概念,包括如何使用指针进行数组操作、字符串处理以及动态内存分配和释放。通过具体示例,如冒泡排序、字符串复制和拼接,展示了指针的强大功能。同时,讲解了如何动态申请和释放内存,以实现高效的数据管理和资源利用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.返回值是指针的函数: 指针函数,不能用它返回局部变量。
2.数组的指针 int (p)[10] 指针的变量为p 数据类型为int( )[10];

int main(void)
{
	int a[][5] = {1,2,3,4,5,  6,7,8,9,10,  11,12,13,14,15,  16,17};

	int (*p)[5] = a;   //此处 a <==> &a[0]

	printf("%d\n", *((int *)(p + 4) - 12));  //输出结果为 9

	return 0;
}


用指针的方法写出冒泡排序算法。

void swap(int *p1, int *p2)
{
	int t = *p1;
	*p1 = *p2;
	*p2 = t;
}

void bubbleSort(int *begin, int *end)
{
	for(;end > begin;--end)
	{
		int *p = begin;
		for(;p < end;++p)
		{
			if(*p > *(p + 1))
			{
				swap(p, p + 1);
			}
		}
	}
}

int main(void)
{
	int a[] = {1,-2,3,-4,5,-6,7,-8,9,0};
	int i;
	bubbleSort(a, a + sizeof(a) / sizeof(a[0]) - 1);  //使用指针的方式可以很方便的排序此数组中任何区间的数
  //bubbleSort(a + 2, a + sizeof(a) / sizeof(a[0]) - 4); 

	for(i = 0;i < sizeof(a) / sizeof(a[0]);++i)
	{
		printf("%d\n", a[i]);
	}

	return 0;
}


写一方法验证,所使用的计算机使用的是大端还是小端存储方式。

#include <stdio.h>
int main(void)
{

	int i = 0x12345678;
	char *p;
	short *q;
	p = (char *)&i;
	printf("%x\n", *p);   //此处打印出来是78
	
	q = (short *)&i;
	printf("%d\n", *p);  //此处打印出来是5678
	return 0;
}

//先定位再偏移然后再访问偏移过的地址的内存;


用指针的方式写出 Strlen,要求不能定义变量,不能使用 for 循环等。
分析:此类问题使用递归方法解决。

size_t Strlen(const char *p)
{
	if(*p == '\0')
	{
		return 0;
	}
	else
	{
		return Strlen(p + 1) + 1;
	}
}


用指针的方式写出 Strcpy 函数

void Strcpy(char *dest, const char *src)
{
	while(*src)
	{
		*dest = *src;
		++dest;
		++src;
	}
	
	*dest = '\0';
}

//下面这种方法为上面方法的优化。
void Strcpy(char *dest, const char *src)
{
	while((*dest++ = *src++));
}


用指针的方式写一个比较函数,比较两个字符串数组。
分析:当取出的两个字符都不为0 并且两个字符相等时,只要把地址向后移就行了,
如果不满足上面条件就将两个字符做差,通过结果是否大于0, 小于0 或等于0得出比较结果。

#include <stdio.h>
int Strcmp(const char *p1, const char *p2)
{

	while(*p1 && *p2 && *p1 == *p2)
	{
		++p1;
		++p2;
	}
	return *p1 - *p2;

}
int main(void)
{

	char s[100] = "helllo";
	char ss[100] = "world";
	printf("%d\n", Strcmp(s, ss));
	return 0;

}


用指针的方式写出Strcat函数。

void Strcat(char *dest, char *src)
{

	while(*dest)
	{
		++dest;
	}
	while(*src)
	{
		*dest = *src;
		++dest;
		++src;
	}
   *dest = 0;

}

int main(void)
{

	char s[100] = "hello";
	char ss[100] = "world";
	
	Strcat(s, ss);
	puts(s);
	return 0;

}


动态拷贝函数:

void *Memcpy(void *dest, const void *src, size_t len)
{
	void *ret = dest;
	int i;
	char *p1 = (char *)dest;  //short,,, int 
	char *p2 = (char *)src;
	for(i = 0;i < len;++i)
	{
		p1[i] = p2[i];
	}
	return ret;
}

int main(void)
{
	double a[10] = {1,2,3,4,5,6,7,8,9,0};

	double b[10];

	Memcpy(b, a, sizeof(a));
	
	int i;
	for(i = 0;i < sizeof(a) / sizeof(a[0]);++i)
	{
		printf("%f\n", b[i]);
	}

	return 0;
}


动态申请一块内存,将hello写进去, 再新开一块内存将原来的字符串拷贝过去,在后面再加上新的字符串。

#include <stdio.h>
int main(void)
{

char *p;
p = malloc(strlen("hello") + 1);
if(p != NULL) //此处判断是否成功开辟了一块空间。
{

	strcpy(p,"hello");
	 puts(p);
	 char *q;
/*	 q = malloc(strlen("hello") + strlen("world") + 1);
	 if(q != NULL)
	{
		strcpy(q, p);
		strcat(q, "world");
		puts(q);
		free(q);
		q = NULL;

	}
	 free(p);
	 p = NULL;*/

	 p = realloc(p, (strlen("hello") + strlen("world") + 1));
	 strcat(p, "world");
	 puts(p);
	
	 free(p);
	 p = NULL;
}
return 0;

}



在堆上开辟动态内存,将n项斐波那契写入里面:

注意;申请的内存记得要释放不然会造成内存泄漏。

#include <stdlib.h>
int fib(int n)
{
	if(1 == n || 2 == n)
	{
		return 1;
	}
	else
	{
		return fib(n - 1) + fib(n - 2);
	}
}

int main(void)
{
	malloc(1024 * 1024 * 500)
	int *p;
	int len = 10;
	p = malloc(len * sizeof(int));

	if(p != NULL)
	{
		int i;
		for(i = 0;i < len;++i)
		{
			p[i] = fib(i + 1);
		}

	
	int *q;
	int len2 = 20;
	q = malloc(len2 * sizeof(int));
	if(q != NULL)
	{
		memcpy(q, p, len * sizeof(int));
		for(i = 10;i < len2;++i)
		{
			q[i] = fib(i + 1);
		}
		for(i = 0;i < len2;++i)
		{
			printf("%d\n", q[i]);
		}
		free(q);
	}

	free(p);
	p = NULL;  //说明状态 p 不可用
}


puts("Hello");

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值