您好,欢迎来到爱够旅游网。
搜索
您的当前位置:首页C语言指针详解-包过系列(二)目录版

C语言指针详解-包过系列(二)目录版

来源:爱够旅游网

1、数组名的深入理解

1.1、数组名的本质

#include<stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    printf("&arr[0] = %p\n ", &arr[0]);//取数组首元素地址
    printf("arr     = %p\n ", arr);//取数组数组名
    return 0;
}

#include<stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    printf("%d", sizeof(arr));
    return 0;
}

1.2、数组名本质的两个例外

1.2.1、sizeof(数组名)

在关键字 sizeof 中单独放入数组名时,这个数组名表示的是整个数组,计算的是整个数组的大小,单位是字节。如上 1.1 中所示。
注意:只有是单独放入数组名时,数组名才表示整个数组,其余情况下均是计算数据类型大小。
如下面代码所示:

#include<stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    printf("%d", sizeof(arr + 1));//此时 arr 就又恢复成数组首元素的地址了
    return 0;
}

在 x86 环境下的运行结果:

1.2.2、&数组名
#include<stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    printf("&arr[0] = %p\n", &arr[0]);
    printf("arr     = %p\n",  arr   );
    printf("&arr    = %p\n", &arr   );
    return 0;
}

#include<stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    printf("&arr[0] = %p\n", &arr[0]);
    printf("&arr[0] + 1 = %p\n", &arr[0] + 1);

    printf("arr     = %p\n",  arr   );
    printf("arr + 1 = %p\n", arr + 1);

    printf("&arr     = %p\n", &arr);
    printf("&arr + 1 = %p\n", &arr + 1);
    
    return 0;
}

2、使用指针访问数组

#include<stdio.h>
int main()
{
    int arr[10] = { 0 };
    int i = 0;
    size_t sz = sizeof(arr) / sizeof(arr[0]);
    int* parr = arr;//将数组首元素地址存储到指针 parr 中
    //输入
    for (i = 0; i < sz; i++)
    {
        scanf("%d", parr + i);//遍历数组地址
        //注意,这里parr+i就已经表示数组对应下标元素的地址了,&parr+i表示的就是指针变量parr的地址加减整数了。
        //scanf("%d", arr + i);也可以这样写
    }
    //输出
    for (i = 0; i < sz; i++)
    {
        printf("parr[%d] = %d\n", i, *(parr + i));//输出数组元素
    }
    return 0;
}

#include<stdio.h>
int main()
{
    int arr[10] = { 0 };
    int i = 0;
    size_t sz = sizeof(arr) / sizeof(arr[0]);
    int* parr = arr;//将数组首元素地址存储到指针 parr 中
    //输入
    for (i = 0; i < sz; i++)
    {
        scanf("%d", parr + i);
    }
    //输出
    for (i = 0; i < sz; i++)
    {
        printf("parr[%d] = %d\n", i, parr[i]);//等价于arr[i]
    }
    return 0;
}

3、一维数组传参本质

在之前函数章节,我们已经讲过数组可以作为参数传递给函数,在本节我们讲述一下数组传参本质。
我们先用一个问题来作引,我们之前在函数外部计算过数组元素的个数,在本节我们不妨尝试在函数内部计算求数组元素个数。

#include<stdio.h>

void test(int arr[])
{
    size_t sz2 = sizeof(arr) / sizeof(arr[0]);
    printf("sz2 = %d\n", sz2);
}

int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    size_t sz1 = sizeof(arr) / sizeof(arr[0]);
    printf("sz1 = %d\n", sz1);
    test(arr);
    return 0;
}
sizeof(arr)/sizeof(arr[0]) == 8/4 == 2
#include<stdio.h>

void test(int* arr)
{
    printf("%d\n", sizeof(arr));//计算一个指针变量的大小
}

int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    size_t sz1 = sizeof(arr) / sizeof(arr[0]);//计算数组内元素个数多少。
    printf("sz1 = %d\n", sz1);
    test(arr);
    return 0;
}

4、二级指针

4.1、二级指针介绍

#include<stdio.h>
int main()
{
    int a = 0;
    int* p = &a;//一级指针p存储a的地址
    int** pp = &p;//二级指针存储p的地址
        printf("p = %p\n", p);
        printf("pp = %p\n", pp);
    return 0;
}

4.2、二级指针运算

#include<stdio.h>
int main()
{
    int a = 0;
    int b = 10;
    int* p = &a;//一级指针p存储a的地址
    int** pp = &p;//二级指针存储p的地址
    *pp = &b;//通过解引用更改一级指针 p 所指向的对象
    printf("%d", *p);
    return 0;
}


2、**pp 先通过*pp 找到 p 然后再通过对 p 解引用找到 a。

#include<stdio.h>
int main()
{
    int a = 0;
    int* p = &a;//一级指针p存储a的地址
    int** pp = &p;//二级指针存储p的地址
    **pp = 20;//通过两次解引用更改一级指针 p 所指向的对象的内容。
    //等价于*p =20
    //等价于 a = 20
    printf("%d", a);
    return 0;
}

5、指针数组(模拟实现二维数组)

我们知道有整型数组,字符型数组,浮点型数组等,由此可知指针数组就是存储的元素是指针的数组。指针数组的每个元素又指向一块区域。
我们用指针数组模拟二维数组为例:
首先先编写好3个一维数组:

#include<stdio.h>
int main()
{
    int arr1[] = { 1,2,3,4,5 };
    int arr2[] = { 6,7,8,9,10 };
    int arr3[] = { 11,12,13,14,15 };
    return 0;
}
#include<stdio.h>
int main()
{
    int arr1[] = { 1,2,3,4,5 };
    int arr2[] = { 6,7,8,9,10 };
    int arr3[] = { 11,12,13,14,15 };
    int* arr[] = { arr1 , arr2 , arr3 };//编写指针数组
    int i = 0;
    for (i = 0; i < 3; i++)//打印模拟的二维数组
    {
        int j = 0;
        for (j = 0; j < 5; j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}



上述代码只是模拟出了二维数组的效果,但并不是完全等于二维数组,因为上面模拟出的数组的每一行并不是连续的。

全文至此结束!!!
写作不易,不知各位老板能否给个一键三连或是一个免费的赞呢(-▽-)(-▽-),这将是对我最大的肯定与支持!!!谢谢!!!(-▽-)(-▽-)

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务