【C语言】指针

发布时间 2024-01-12 23:40:30作者: hzyuan

指针的定义

如果在程序中定义了一个变量,那么在对程序进行编译时,系统就会给这个变量分配内存单元,按变量地址存取变量值的方式称为直接访问,如printf("%d",i);scanf("%d",&i);;另一种存取变量值的方式称为间接访问,即将变量i的地址存放到另一个变量中,在C语言中,指针变量就是用来存放变量地址的特殊变量。
指针变量的定义格式如下:

// 基类型 *指针变量名;
    int *i_pointer;

指针和指针变量是两个概念:一个变量的地址称为该变量的“指针”。如果有一个变量专门用来存放另一个变量的地址(即指针),那么称它为“指针变量”,i_pointer 就是一个指针变量。

i_pointer 所占内存空间取决于体系结构、编译器实现。

取地址操作符和取值操作符

取地址操作符为&,也称引用。通过该操作符我们可以获取一个变量的地址值。
取值操作符为*,也称解引用。通过该操作符我们可以得到一个地址对应的数据。

#include <stdio.h>

int main() {
    int i=5,*p=&i; //指针变量名是p,而不是*p
    printf("i=%d\n",i); //直接访问
    printf("*p=%d\n",*p); //间接访问
    return 0;
}

p为整型变量指针,在解引用时会访问4字节大小的空间,同时以整型值对内存进行解析。

指针的传递

指针的使用场景通常有两个,即传递与偏移。

C语言的函数调用均为值传递。如下例:

#include <stdio.h>

void change(int i) {
    i=5;
}

int main() {
    int i=10;
    printf("before change i=%d\n",i);
    change(i);
    printf("after change i=%d\n",i);
    return 0;
}

当 main 函数开始执行时,系统会为 main 函数开辟函数栈空间,当程序走到 int i 时,main 函数的栈空间会为变量 i 分配4字节大小的空间。调用 change 函数时,系统会为 change 函数重新分配新的函数栈空间,并为形参变量 j 分配4字节大小的空间,在调用 change(i) 时,实际上是将 i 的值赋值给 j。因此在 change 函数的函数栈空间修改变量 j 的值后,change 函数执行结束,释放其栈空间,j 就不再存在,i 的值不会改变。

通过指针就可以在子函数中修改main函数内的变量的值。

#include <stdio.h>

void change(int *j) {
    *j=5;
}

int main() {
    int i=10;
    printf("before change i=%d\n",i);
    change(&i);
    printf("after change i=%d\n",i);
    return 0;
}

将变量 i 的地址传递给 change 函数后,通过 *j 就间接访问到了与变量 i 相同的区域。

指针的偏移

指针的偏移即对指针进行加减,加就是向后偏移,减就是向前偏移。

#include <stdio.h>

#define N 5
int main() {
    int a[N]={11,22,33,44,55};
    int *p;
    p = a; //保证等号两边的数值类型一致
    for (int i = 0; i < N; ++i) { //正序输出
        printf("%-3d",*(p+i));
    }
    printf("\n--------------\n");
    p=&a[N-1]; //p指向最后一个元素
    for (int i = 0; i < N; ++i) { //逆序输出
        printf("%-3d",*(p-i));
    }
    printf("\n");
    return 0;
}

执行结果:

指针变量加1后,偏移的长度是其基类型的长度,通过 *(p+1) 就可以得到 a[1]。

指针与一维数组

一维数组的数组名中存储的是数组的首地址。C语言的子函数形参位置并没有数组变量的设计,把数组名作为实参传递给子函数时,是弱化为指针的,形参接收到的是数组名内存储的数组的起始地址。

#include <stdio.h>

void change(char *d) {
    *d='H';
    d[1]='E'; //下标法
    *(d+2)='L'; //指针法
}

int main() {
    char c[10]="hello";
    change(c);
    puts(c);
    return 0;
}

执行结果: