1. 指针基础练习:演示p++
、++p
和(*p)++
的区别
核心目的:区分指针自增与指针指向值自增的不同逻辑,理解运算符优先级对指针操作的影响。
#include <stdio.h>
void arr1()
{
int arr[] = {11,13,15,17,19};
int *p = arr;
printf("结果1:%d\n",*p); //结果为11
}
void arr2()
{
int arr[] = {11,13,15,17,19};
int *p = arr;
int x = *p++;
printf("结果2:%d,%d\n",x,*p); //11,13
}
void arr3()
{
int arr[] = {11,13,15,17,19};
int *p = arr;
int y = *(++p);
printf("结果3:%d,%d\n",y,*p); //13,13
}
void arr4()
{
int arr[] = {11,13,15,17,19};
int *p = arr;
int z = (*p)++;
printf("结果4:%d,%d\n",z,*p); //11,12
}
int main()
{
arr1();
arr2();
arr3();
arr4();
return 0;
}
结果:
原理:
*p++
:优先级上++
高于*
,但++
后置时先执行*p
(取当前值),再让p
指向后一个元素。*++p
:++
前置时先让p
指向后一个元素,再执行*p
(取新指向的值)。(*p)++
:通过括号提升*
的优先级,先取p
指向的值,再对该值进行自增(指针p
的指向不变)。
2. 数值交换函数:通过指针修改原变量值
核心目的:演示如何通过指针传递变量地址,在函数内部修改外部变量的值(解决函数参数 “值传递” 无法修改原变量的问题)。
#include <stdio.h>
//数值交换
void swap(int *p_a,int*p_b)
{
int time;
//交换
time= *p_a;
*p_a = *p_b;
*p_b = time;
printf("交换后:%d,%d\n",*p_a,*p_b); //
}
int main()
{
int a = 3,b = 4;
printf("交换前:%d,%d\n",a,b); //3,4
swap(&a,&b);
return 0;
}
结果:
原理:
- 函数参数
int *a
和int *b
接收变量的地址,*a
和*b
表示 “地址指向的变量”。 - 通过指针直接操作原变量的内存空间,实现了外部变量的值交换(若用普通变量参数,只能交换函数内部的副本,不影响外部变量)。
3. 指针交换函数:仅交换局部指针变量
核心目的:演示 “指针变量本身也是值”,若仅传递指针变量的副本,函数内部交换指针不会影响外部指针的指向。
#include <stdio.h>
//指针指向
void swap(int *p_a,int*p_b)
{
int *p_t;
//交换
p_t= p_a;
p_a = p_b;
p_b = p_t;
printf("交换后:%d,%d\n",*p_a,*p_b); //
}
int main()
{
int a = 3,b = 4;
printf("交换前:%d,%d\n",a,b); //3,4
swap(&a,&b);
return 0;
}
结果:
原理:
- 函数
swap_ptr
接收的是指针p
和q
的副本(值传递),内部交换的是副本的指向,外部原指针p
和q
的指向不受影响。 - 若要通过函数交换外部指针的指向,需使用 “二级指针”(指针的指针),如
void swap_ptr(int **a, int **b)
。
4. 数组翻转函数:通过指针操作实现数组逆序
核心目的:演示如何通过指针遍历数组,并通过地址计算实现数组元素的逆序(无需额外数组,原地翻转)。
#include <stdio.h>
void inv1(int arr[],int len)
{
register int i = 0,temp;
for(;i < len/2 ; i++)
{
temp = arr[i];
arr[i] = arr[len - i - 1];
arr[len - i - 1] = temp;
}
}
void list(const int *arr,int len)
{
const int *p = arr;
for(;p < arr + len;p++)printf("%-4d",*p);
printf("\n");
}
int main(int argc,char *argv[])
{
int arr[] = {1,3,5,6,9,2,7,33};
int len = sizeof(arr) / sizeof(arr[0]);
list(arr,len);
inv1(arr,len);
list(arr,len);
return 0;
}
结果:
原理:
- 定义
left
(首元素指针)和right
(尾元素指针),通过left < right
控制循环(只需交换一半元素)。 - 每次交换
left
和right
指向的元素,然后分别移动指针向中间靠拢,最终实现数组逆序。 - 指针操作避免了数组下标计算,更直接地操作内存地址,效率与下标访问一致(编译器通常会将下标优化为指针)。
总结
这四个实例从基础到应用,覆盖了指针的核心操作:
- 指针运算(自增、优先级)影响指向与值的逻辑;
- 指针作为函数参数时,可实现对外部变量的修改(值传递 vs 地址传递);
- 指针与数组结合时,可通过地址计算高效操作数组元素。