前面已经介绍了最基本的指针概念指针(一)以及二级指针,接下来我们学习指针在数组和字符串中的应用。
数组指针
通过指针遍历数组(一)
首先我们给出一个数组,如何通过指针来遍历数组中所有元素?
#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;
}
运行结果:

完全正确~
数组元素找第二大值
当然,这个问题最简单的就是排个序,找出第二个就行。但是这里我们要求不进行排序的情况下用指针实现。
我们先来理下思路:
- 要找到数组中第二大的数肯定要遍历数组
- 需要逐个对比大小
具体实现:
- 第一步,定义两个变量,max:代表最大,s_max:代表第二大;
- 我们假设数组中第一个元素是最大值,第二个元素是第二大值
- 遍历数组,如果遇到第i个元素比max大,那么就让当前max的值先存放在s_max中,并且把现在的max的值改为当前第i个元素
- 如果遇到第n个元素,比max小,但是比s_max大,那么就把s_max改为这第n个元素
- 遍历完整个数组后,就找到了第二大的元素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;
}
运行结果:

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

3326

被折叠的 条评论
为什么被折叠?



