C语言指针(三):数组指针和字符串指针

本文详细讲解了C语言中指针在数组和字符串操作中的应用,包括如何通过指针遍历数组并找到最大值、最小值,数组的逆置,以及如何利用指针计算字符串长度和合并字符串。文中通过实例代码展示了各种操作的过程和结果。

前面已经介绍了最基本的指针概念指针(一)以及二级指针,接下来我们学习指针在数组和字符串中的应用。

数组指针

通过指针遍历数组(一)

首先我们给出一个数组,如何通过指针来遍历数组中所有元素?

#include <stdio.h>
int main(){
    int arr[] = { 1, 2, 3, 4, 5 };
    /*
	sizeof(arr)就是整个数组所有元素一共占用的内存大小
	sizeof(int)就是一个int型数据占用的内存大小
	sizeof(arr) / sizeof(int)就是数组的长度
	*/
    int len = sizeof(arr) / sizeof(int);  //求数组长度
    										
    int i;
    for(i=0; i<len; i++){
    /*
	arr 是数组名,指向数组的第 0 个元素,表示数组首地址
	arr+i 指向数组的第 i 个元素,*(arr+i) 表示取第 i 个元素的数据
	*/
        printf("%d  ", *(arr+i) );  //*(arr+i)等价于arr[i]
    }
    printf("\n");
    return 0;
}

运行结果:
在这里插入图片描述

通过指针遍历数组(二)

我们通过另外一种方式,单独定义一个指针,指向数组

#include <stdio.h>

int main(){
    int arr[] = { 1, 3, 5, 7, 9 };
    int i, *p = arr, len = sizeof(arr) / sizeof(int);

    for(i=0; i<len; i++){
        printf("%d  ", *(p+i) );
    }
    printf("\n");
    return 0;
}

运行结果:
在这里插入图片描述

通过指针遍历数组(三)

对指针变量进行加法和减法运算时,是根据数据类型的长度来计算的。如果一个指针变量 p 指向了数组的开头,那么 p+i 就指向数组的第 i 个元素;如果 p 指向了数组的第 n 个元素,那么 p+i 就是指向第 n+i 个元素;而不管 p 指向了数组的第几个元素,p+1 总是指向下一个元素,p-1 也总是指向上一个元素。

#include <stdio.h>

int main(){
    int arr[] = { 1, 3, 5, 7, 9 };
    int *p = &arr[2];  //也可以写作 int *p = arr + 2;

    printf("%d, %d, %d, %d, %d\n", *(p-2), *(p-1), *p, *(p+1), *(p+2) );
    return 0;
}

运行结果:
在这里插入图片描述

通过指针遍历数组(四)

借助自增运算符来遍历数组元素:

#include <stdio.h>

int main(){
    int arr[] = { 1, 3, 5, 7, 9 };
    int i, *p = arr, len = sizeof(arr) / sizeof(int);

    for(i=0; i<len; i++){
        printf("%d  ", *p++ );
    }
    printf("\n");
    return 0;
}

运行结果:
在这里插入图片描述

数组指针易混淆点

如果p是指向数组 arr 中第 n 个元素的指针,那么 * p++、*++p、(*p)++ 分别是什么意思呢?

  • *p++ 等价于 *(p++),表示先取得第 n 个元素的值,再将 p 指向下一个元素
  • *++p 等价于 *(++p),会先进行 ++p 运算,使得 p 的值增加,指向下一个元素,整体上相当于 *(p+1),所以会获得第 n+1 个数组元素的值。
  • (*p)++ 就非常简单了,会先取得第 n 个元素的值,再对该元素的值加 1。

数组元素找最大值

首先我们看下不用指针的方式:

#include <stdio.h>

int max(int s[])
{
	int value = s[0];
	int i;
	for (i = 1;i<10;i++)
	{
		if(value < s[i])
		{
			value = s[i];
		}
	}
	
	return value;
}

int main(){
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
    int i = max(buf);
	printf("最大值:%d\n",i);
	
	return 0;
}

运行结果:
在这里插入图片描述
现在我们把上面的代码改为用指针的方式:

#include <stdio.h>

int max(int *s)
{
	int value = *s;
	int i;
	for (i = 1;i<10;i++)
	{
		if(value < *(s+i))
		{
			value = *(s+i);
		}
	}
	
	return value;
}

int main(){
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
    int i = max(buf);
	printf("最大值:%d\n",i);
	
	return 0;
}

运行结果:
在这里插入图片描述

数组逆置

现在我们将一个数组比如{1,2,3,4,5}变为{5,4,3,2,1},这样反转过来。
先看下不用指针的常见做法:

#include <stdio.h>

int printf_buf(int arr[])
{
	int i;
	for(i=0;i<10;i++)
	{
		printf("%d ",arr[i]);
	}	 
	return 0;
}

int main(){
	int low = 0;
	int high = 9;
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
	while(low<high)
	{
		int temp = buf[low];
		buf[low] = buf[high];
		buf[high] = temp;
		low++;
		high--;
	}
	
	printf_buf(buf);
	return 0;
}

运行结果:
在这里插入图片描述
这个问题也可以用递归函数解决,在之前的博客里可以看到:递归函数
现在我们用指针的方式解决:

#include <stdio.h>

int printf_buf(int arr[])
{
	int i;
	for(i=0;i<10;i++)
	{
		printf("%d ",arr[i]);
	}	 
	return 0;
}

int main(){

    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };

	int *start = &buf[0];
	int *end = &buf[9];
	while(start<end)
	{
		int temp = *start;
		*start = *end;
		*end = temp;
		
		start++;
		end--;
	}
	
	printf_buf(buf);
	return 0;
}

运行结果:
在这里插入图片描述
完全正确~

数组元素找第二大值

当然,这个问题最简单的就是排个序,找出第二个就行。但是这里我们要求不进行排序的情况下用指针实现。
我们先来理下思路:

  • 要找到数组中第二大的数肯定要遍历数组
  • 需要逐个对比大小

具体实现:

  1. 第一步,定义两个变量,max:代表最大,s_max:代表第二大;
  2. 我们假设数组中第一个元素是最大值,第二个元素是第二大值
  3. 遍历数组,如果遇到第i个元素比max大,那么就让当前max的值先存放在s_max中,并且把现在的max的值改为当前第i个元素
  4. 如果遇到第n个元素,比max小,但是比s_max大,那么就把s_max改为这第n个元素
  5. 遍历完整个数组后,就找到了第二大的元素s_max;

还是先用数组下标的方式实现:

#include <stdio.h>

int smax(int s[])
{
	int max;
	int s_max;
	max = s[0];
	s_max = s[1];
	int i;
	for(i=0;i<10;i++)
	{
		if(max < s[i])
		{
			s_max = max;
			max = s[i];
		}
		else if(max > s[i] && s_max < s[i])
		{
			s_max = s[i];
		}
	}
	return s_max;

}

int main()
{
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
	printf("第二大的元素是:%d\n",smax(buf));
	
	return 0;
}

运行结果:
在这里插入图片描述
结果完全正确,第二大的元素确实是65

现在把上面代码改为用指针的方式:

#include <stdio.h>

int smax(int *s)
{
	int max;
	int s_max;
	max = *s;
	s_max = *(s+1);
	int i;
	for(i=0;i<10;i++)
	{
		if(max < *(s+i))
		{
			s_max = max;
			max = *(s+i);
		}
		else if(max > *(s+i) && s_max < *(s+i))
		{
			s_max = *(s+i);
		}
	}
	return s_max;

}

int main()
{
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
	printf("第二大的元素是:%d\n",smax(buf));
	
	return 0;
}

运行结果:
在这里插入图片描述
完全正确!

字符串指针

计算字符串长度

我们给出一个字符串,通过指针来实现字符串长度的计算,不使用数组下标。

#include <stdio.h>

int main()
{
	char s1[100] = "hello";	
	char *p = s1;
	int len = 0;
	
	while(*p)	//*p的内容为0时,表示字符串结束了
	{
		p++;
		len++;
	}
	
	printf("字符串长度为%d\n",len);
	return 0;
} 

运行结果:
在这里插入图片描述

合并字符串

通过指针把两个字符串数组合并为一个

#include <stdio.h>

int main()
{
	char s1[100] = "hello";	
	char s2[100] = " world"; 
	char *p1 = s1;
	char *p2 = s2;
	
	while(*p1)
	{
		p1++;
	}
	
	while(*p2)
	{
		*p1 = *p2;//从s1的最后开始,从s2的首元素开始 
		p2++;
		p1++;
	}
	
	printf("%s\n",s1);
	return 0;
} 

运行结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值