C 语言中一些有关于指针的概念

2018/07/14 C

指针对于 C 语言来说是很重要的一部分,也比较难理解,我也觉得有必要写一篇关于指针的笔记,方便以后自己查看。

什么是指针

从根本上看,指针 (pointer) 是一个值为内存地址的变量(或数据对象)。如果我声明一个指针:int *p,那么我就可以利用&运算符来给这个指针赋值,p=&test。要创建一个指针变量,就要先声明指针的类型。例如上面的声明就叫做将p指向为存储int类型变量地址的指针。我们可以使用*运算符来获得存储在对应地址中的值。

另外,是不可以直接对于一个指针变量做这种神奇的操作的:*p=233。原因是因为所有的本地变量都不会有默认的初始值,int *p;的时候,p这个指针是没有值的,如果强行*p=233,但是p中是没有一个明确的初始值的,p可能会指向一片莫名奇妙的地方,这个地方的值你也是未知的,所以,当进行赋值操作的时候,就会覆盖原来的值,万一那个地方是不能写入的,那么程序就 GG 了。所以任何一个地址变量没有被赋值之前,是不能通过*p这种方式去访问 / 获得新的变量的。

指针应用场景(一)

  • 交换两个变量的值
int main(){
    int a=1;
    int b=2;

    swap(&a,&b);
    printf("a=%d,b=%d\n",a,b);
}

void swap(int *pa,int *pb){
    printf("a=%d,b=%d\n",*pa,*pb);
    int t=*pa;
    *pa=*pb;
    *pb=t;
}

输出结果:
a=1,b=2
a=2,b=1

之前还有一个采用的是值传递的传值方式,这种方式并不会影响ab的值,因为值传递仅仅只是交换了ab副本的值。所以我这里用的地址传递的方式,通过将函数参数声明为指针,来直接操作对应地址上的变量。指针参数使得被调用的函数能够访问和修改主调函数中对象的值。

指针应用场景(二)

  • 函数返回多个值,某些值就只能通过指针返回
  • 传入的参数实际上是需要保存带回的结果的变量
int main(){
    int a[] = {3, 5, 7, 1, 4};
    int min, max;
    minmax(a, sizeof(a) / sizeof(a[0]), &min, &max);
    printf("min=%d,max=%d", min, max);
}

void minmax(int a[], int len, int *min, int *max) {
    int i;
    *min = *max = a[0];
    for (i = 0; i < len; i++) {
        if (a[i] < *min) {
            *min = a[i];
        }
        if (a[i] > *max) {
            *max = a[i];
        }
    }
}

输出结果:
min=1,max=7

你又可以看到在minmax()这个函数中,我们需要的是两个返回结果,所以这里用的是两个指针参数,主函数中的sizeof(a) / sizeof(a[0]),得到的是数组a[]中的元素的个数,然后用两个指针minmax,把我要接收两个地址传进去,传进函数后,最大值和最小值就会根据条件进行赋值运算,前面说到,由于这是指针参数,所以最终它们的值会传回来。

数组名根本不是指针

sizeof(a) != sizeof(int*)
  • 指针里面装的是地址
  • 之所以数组名可以像指针那样用,是因为数组名会被隐式转换为指针
int sum(int *ar,int n) == int sum(int ar[],int n) //类型不等价,参数表中等价

为了更好的理解,引用以下解释

当使用sizeof运算符时,另一个区别很明显。如上所述,当您获取数组名称的大小时,将获得数组中所有元素占用的总字节数。当您获取指针变量的大小时,您将获得指针变量本身占用的字节数。所以,如果我们环境中的指针是4个字节(并且在所有环境中都不是这种情况),那么sizeof(p)会给我们4个指针变量的大小……不是指向它的数组的大小。

将阵列想象为固定位置处的一大块内存。数组的名称是数组的地址,不能更改。另一方面,指针变量只是一个包含某个地址的变量,您可以通过在该变量中存储不同的地址来更改它的内容……以便它指向数组的不同元素或不同的地址阵列完全。

Search

    Table of Contents