如何理解c语言指针

理解指针的关键在于理解变量,变量是一个“魔术盒”,学习内存和内存地址之后,我们应该将变量看作占据一部分内存空间的对象来理解,从而更好的进行运用。

在调用函数时,值的传递是单向的,即从实参传向形参,例如,我们已经有了一个计算两数和差的函数func(int num1,int num2,int sum,int diff),而当我们真正想利用这个函数求出两个数的和与差时却出现问题,因为函数的返回值只能是一个,而当我们重新定义一个初始化的变量带入后,这个变量的值并不会改变。例如:

int a=1,int b=2,int c=0,int d=0.

func(a,b,c,d)

此时调用函数之后abcd的值仍会保持不变,因为函数作用后的值并没有传递回来。而指针就能有效解决这个问题。

内存空间是广阔的,每个对象都占据着一定的内存空间,于是我们需要位置这个概念,即内存地址。取址运算符是&,我们只需将&加在对象名前面就可以得到该对象的位置,例如:

printf("%p",&a)就可以得到变量a的位置,其中%p是占位符,值得注意的是,内存的编码是以字节为基础的(8bit),而一个变量可能会占据不止一个字节,而由于对象占据的地址是连续的,我们只需要用对象占据内存空间的首地址来表明该对象的地址。

只显示一个对象的地址用处是不大,我们需要利用这个地址对对象进行操作。

定义指针变量int*p,与之区分的是int p。

这两者的区别在于后者是存储整数的盒子,前者加上*作为区分,标明是存放整数对象地址的盒子。对指针变量赋值时,是要将某个对象的位置赋值给指针变量,故需要加上取址运算符。如:

int a=10;

int*p=&a;

这就将a的地址赋值给变量p了。

此时就说p指向了a。

那么怎么从p得到a具体的值呢,我们就需要用到指针运算符,*p即为a的值,其中*为指针(又名间接访问运算符,这里的间接性在于利用a的地址间接的访问了a的值)运算符,换言之,*p就是a的别名。那么,这一切的做法有什么用处呢?

作为函数参数的指针

在最开始举出的例子中,形参的修改只是临时性的复制,无法反映到主调函数(主动调用其他函数的函数)的实参中,而利用指针能有效解决这个问题。

在 C 语言中,当以变量为实参调用函数时,函数是按值传递的,这意味着传递给函数的是变量的值的副本,而不是变量本身。函数内部对这个副本进行操作,不会影响到原始变量的值。

#include <stdio.h>

// 函数,交换两个变量的值
void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 5, y = 10;
    printf("交换前:x = %d, y = %d\n", x, y);
    swap(x, y);
    printf("交换后:x = %d, y = %d\n", x, y);
    return 0;
}

在这个例子中,swap函数接收的是xy的副本,对副本进行交换操作,不会影响到xy的原始值而当以变量的地址作为实参时,函数可以通过指针来间接访问和修改原始变量的值,因为指针存储的是变量的地址。

#include <stdio.h>

// 函数,交换两个变量的值
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 5, y = 10;
    printf("交换前:x = %d, y = %d\n", x, y);
    swap(&x, &y);
    printf("交换后:x = %d, y = %d\n", x, y);
    return 0;
}

在这个改进的例子中,swap函数接收的是指向xy的指针(即&x&y)。通过指针操作(使用*运算符解引用),可以修改xy的实际值。

类似的,在讲到scanf函数时,强调第二个参数前必须加上&,原因与此类似,在这个函数中,我们试图将某个接收到的值赋值给一个变量,就不能不利用指针对这个变量进行间接操作。

数组与指针

  • 数组名是指针常量

    • 当声明一个数组时,例如 int arr[5];,数组名 arr 实际上是一个指向数组第一个元素的指针常量。
    • 这意味着 arr 存储了数组第一个元素的地址,即 &arr[0]
  • 通过指针访问数组元素

    • 可以使用指针来访问数组元素。例如,如果 p 是一个指向 arr 数组的指针,那么 *(p + i) 等同于 arr[i]
    • 这里的 p + i 表示从 p 所指向的位置向后移动 i 个元素的位置,*(p + i) 则是对该位置元素的解引用操作,从而获取该元素的值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值