C语言指针详解

变量的地址

&i 取i变量所在的地址编号,返回i变量的地址编号。

int *pi;//声明指针变量,内存中声明一个一定宽度的内存空间,并把命名为pi。
在这里插入图片描述
pi = &i;//把i地址的编号赋值给pi
在这里插入图片描述
i的内存地址是6,pi变量的值是6,这样pi就指向了变量i。

printf(“%d”,*pi);

*pi表示pi内容所指地址的内容。pi内容是6,pi指向内存编号为6的地址。所以这个值为30。

练习:

char a,*pa;
a = 10;
pa = &a;//将a的地址赋值给pa这个变量
*pa = 20;
printf("%d",a);

const int *pi

	int i1 = 30;
	int i2 = 40;
	const int *pi = &i1;
	
	pi = &i2;
	i2 = 80;
	printf("%d\n",*pi);
	
	return 0;

int *const pi

int i1 = 30; 
int i2 = 40; 
int *const pi = &i1;
i1 = 80; 
printf("%d", *pi); 

总结:

  1. 如果const修饰在* p前,则不能改的是 *p(即不能类似这样:*pi =50;赋值)而不是指pi
  2. 如果const是直接写在pi前,则pi不能改(即不能类似这样:pi=&i;赋值)

函数参数的传递问题

三道考题:

#include<stdio.h>
void Exchg1(int x,int y)
{
	int tmp;
	tmp = x;
	x = y;
	y = tmp;
	printf("x = %d,y = %d\n",x,y);
}
int main()
{
	int a = 4,b = 6;
	Exchg1(a,b);
	printf("a = %d,b= %d\n",a,b);
	return 0;
}

x = , y=. a = , b=

#include<stdio.h>
void Exchg2(int *px,int *py)
{
	int tmp = *px;
	*px = *py;
	*py = tmp;
	printf("*px = %d,*py = %d\n",*px,*py);
}
int main()
{
	int a = 4;
	int b = 6;
	Exchg2(&a,&b);
	printf("a = %d,b= %d\n",a,b);
	return 0;
}

*px=, *py=. a=, b=.

#include<stdio.h>
void Exchg3(int &x,int &y)
{
	int tmp = x;
	x = y;
	y = tmp;
	printf("x = %d,y = %d\n", x, y);
}
int main()
{
	int a = 4;
	int b = 6;
	Exchg3(a,b);
	printf("a = %d,b= %d\n",a,b);
	return 0;
}

x=, y=. a=, b=.

C 语言中函数参数的传递有:值传递、地址传递、引用传递 这三种形式。题一为值传递,题二为地址传递,题三为引用传递。

题目一:

x = 6, y = 4. a = 4, b = 6.

看调用Exch1函数的代码:

main() 
{ 
	int a = 4,b = 6; 
	Exchg1(a, b) /* 这里调用了 Exchg1 函数 */ 
	printf("a = %d, b = %d.\n", a, b); 
} 

Exchg1(a,b)是所完成的操作代码如下所示:

int x = a; /* ← */ 
int y = b; /* ← 注意这里,头两行是调用函数时的隐含操作 */ 
int tmp; 
tmp = x; 
x = y; 
y = tmp;

​ 请注意在调用执行 Exchg1 函数的操作中我人为地加上了头两句: int x = a; int y = b; 这是调用函数时的两个隐含动作。它确实存在,现在我只不过把它显式地 写了出来而已。问题一下就清晰起来啦。

原来 ,其实函数在调用时是隐含地把实参 a、b 的值分别赋值给了 x、y, 之后在你写的 Exchg1 函数体内再也没有对 a、b 进行任何的操作了。交换的只 是 x、y 变量。并不是 a、b。当然 a、b 的值没有改变啦!函数只是把 a、b 的 值通过赋值传递给了 x、y,函数里头操作的只是 x、y 的值并不是 a、b 的值。 这就是所谓的参数的值传递了。

题目二:

*px = 6, *py = 4. a = 6, b = 4.

​ 看调用处:Exchg2(&a, &b);

​ 它将 a 的地址(&a)代入到 px,b 的地址(&b)代入到 py。同上面的值 传递一样,函数调用时作了两个隐含的操作:将&a,&b 的值赋值给了 px、py。

px = &a;

py = &b;

这样,有了头两行的隐含赋值操作。我们现在已经可以看出,指针 px、py 的值已经分别是 a、b 变量的地址值了。接下来,对* px、* py 的操作当然也就 是对 a、b 变量本身的操作了。所以函数里头的交换就是对 a、b 值的交换了, 这就是所谓的地址传递(传递 a、b 的地址给了 px、py)。

题目三:

x = 6, y = 4. a = 6, b = 4.

​ Exchg3 函数的定义处 Exchg3(int &x, int &y)。参数 x、 y 是 int 的变量,调用时我们可以像值传递(如: Exchg1(a, b); )一样调 用函数(如: Exchg3(a, b);)。但是 x、y 前都有一个取地址符号“&”。有 了这个,调用 Exchg3 时函数会将 a、b 分别代替了 x、y 了,我们称:x、y 分别引用了 a、b 变量。这样函数里头操作的其实就是实参 a、b 本身了,也就 是说函数里是可以直接修改到 a、b 的值了。

1)在函数定义格式上有不同: 值传递在定义处是:Exchg1(int x, int y); 引用传递在这义处是:Exchg3(int &x, int &y);

2)调用时有相同的格式: 值传递:Exchg1(a, b); 引用传递:Exchg3(a, b);

3)功能上是不同的: 值传递的函数里操作的不是 a、b 变量本身,只是将 a、b 值赋给了 x、y。 函数里操作的只是 x、y 变量而不是 a、b,显示 a、b 的值不会被 Exchg1 函数 所修改。

​ 引用传递 Exchg3(a, b)函数里是用 a、b 分别代替了 x、y。函数里操作 的就是 a、b 变量的本身,因此 a、b 的值可在函数里被修改的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值