C语言:*p++与p++有何区别

发布于:2025-07-28 ⋅ 阅读:(12) ⋅ 点赞:(0)

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 *aint *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接收的是指针pq的副本(值传递),内部交换的是副本的指向,外部原指针pq的指向不受影响。
  • 若要通过函数交换外部指针的指向,需使用 “二级指针”(指针的指针),如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控制循环(只需交换一半元素)。
  • 每次交换leftright指向的元素,然后分别移动指针向中间靠拢,最终实现数组逆序。
  • 指针操作避免了数组下标计算,更直接地操作内存地址,效率与下标访问一致(编译器通常会将下标优化为指针)。

总结

这四个实例从基础到应用,覆盖了指针的核心操作:

  • 指针运算(自增、优先级)影响指向与值的逻辑;
  • 指针作为函数参数时,可实现对外部变量的修改(值传递 vs 地址传递);
  • 指针与数组结合时,可通过地址计算高效操作数组元素。

网站公告

今日签到

点亮在社区的每一天
去签到