【C语言】指针与地址之间关系

声明:本文是基于征服C指针总结。

什么是指针?

指针”也是一种数据类型(在C语言中,数组也是一种类型),而指针类型的值就是内存的地址,为了更快理解这一概念,实际编程理解一下:

#include <stdio.h>
int main(void)
{
	int a = 5;
	int b = 10;
	int *c;

	/* 输出各变量的地址 */
	printf("&a  %p\n", (void*)&a);
	printf("&b  %p\n", (void*)&b);
	printf("&c  %p\n", (void*)&c);

	/* 把 a 的地址赋给指针变量 c */
	c = &a;
	printf("c  %p\n", (void*)c);

	/* 通过 c 输出 a 的值 */
	printf("*c  %d\n", *c);

	/* 通过 c 更改 a 的值 */
	*c = 10;
	printf("a  %d\n", a);

	return 0;
}

结果:
在这里插入图片描述
在该程序中,第4~6行声明了 int 类型的变量 a 和 b 以及“指向 int 的指针”类型的变量 c 。
其中, int *c;声明的是变量 c ,类型为“指向 int 的指针”。
c = &a;是将 a 的地址赋给指针变量 c (即 c 中保存的是 a 的地址),当指针变量 c 保存了另一个变量 a 的地址时,称为“ c 指向 a ”
第18行代码printf("*c %d\n", *c);,因为前面已经 c 指向 a ,所以 *c 和 a 表示同样的内容,所以也可以通过给 *c 赋值改变 a 的值。

  • 关于声明:
      通常,C语言的声明是这种的:类型 变量名;
      但是在声明指针时,却不是按照此逻辑进行 int* c;,即将*写在靠近类型的一侧。
      虽然说这样符合了类型 变量名;的形式,但是在声明多个变量会出现漏洞。

  • 变量不一定按照声明的顺序保存在内存中

  • void*是可以指向任何类型的指针类型。(关于详解点击此)

  • 对变量使用 & 运算符,可以获取该变量地址,这个地址称为指向该变量的指针。

指针运算

#include <stdio.h>
int main(void)
{
	int x;
	int *y;
	/* 将指向 x 的指针赋给 y */
	y = &x;
	/* 输出 y 的值*/
	printf("y  %p\n", (void*)y);
	/* y 加1 */
	y++;
	printf("y  %p\n", (void*)y);
	printf("y  %p\n", (void*)(y+3));
	return 0;
}

在这里插入图片描述

  • 对于指针的加减运算,标准只允许指针指向数组元素
  • 对指针加 n ,则指针前进“该指针所指向的类型的长度 × n ”

从函数返回多个值

下列程序将main()函数的变量x和y的地址传递给函数get()函数,然后get()将值保存在这两个地址中。

#include <stdio.h>
void get(double* x, double* y)
{
	/* 输出形参x和y的值和地址 */
	printf("x %p,y %p\n", (void*)x, (void*)y);
	printf("&x %p,&y %p\n", (void*)&x, (void*)&y);

	/* 将值保存到参数传递进来的地址中 */
	*x = 1.0;
	*y = 2.0;
}
int main()
{
	double x;
	double y;

	/* 输出变量x和y的地址 */
	printf("&x %p,&y %p\n", (void*)&x, (void*)&y);

	/* 将变量x和y的地址作为参数进行传递 */
	/* get()函数将值保存在该地址中 */
	get(&x, &y);

	/* 输出接收到的值 */
	printf("x %f,y %f\n", x,y);
	return 0;
}

在这里插入图片描述

  • 第18行代码printf("&x %p,&y %p\n", (void*)&x, (void*)&y);,输出的是变量 x、y 地址
  • 第5行代码printf("x %p,y %p\n", (void*)x, (void*)y);,输出的是形参x、y 的值
  • 第6行代码printf("&x %p,&y %p\n", (void*)&x, (void*)&y);,输出形参x、y 地址

但是,下列代码却不能实现 x、y 的赋值:

#include <stdio.h>
void get(double x, double y)
{
	/* 输出形参x和y的值和地址 */
	printf("x %f,y %f\n", x,y);
	printf("&x %p,&y %p\n", (void*)&x, (void*)&y);

	x = 1.0;
	y = 2.0;
}
int main()
{
	double x = 3.0;
	double y = 4.0;

	printf("&x %p,&y %p\n", (void*)&x, (void*)&y);

	get(x, y);

	printf("x %f,y %f\n", x,y);
	return 0;
}

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

  • 根据结果可以发现,main()函数中 x、y 的地址与get()函数中 x、y 地址不同,所以是不同的变量,无论怎样修改get()函数中 x、y 的值都无法改变main()中的值。、
  • 补充:
      实参:调用函数时实际传输的参数
      形参:接收实参的一方。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值