-seventy-
Welcome to my blog space.

指针与数组

/*
    1.指针数组
        ......

    2.数组指针
        ......
*/
// 1.指针数组


/*

# include <stdio.h>

int main()
{    
    // 定义并初始化"数组"
    int arr1[3] = { 1, 2, 3 };    // 数组 arr1[3] -> 里面存的都是 int 类型


    // 定义并初始化"指针数组"
    int* arr2[3] = { 地址1,地址2,地址三 };    // 数组 arr2[3] -> 里面存的都是 int* 类型
    arr2[2] = 新地址;

    return 0;
} 

*/
// 2.数组指针

/*
    定义"数组"指针:
        所指向的数组里面存的数据类型 (*数组指针名称)[所指向的数组的长度];
*/

# include <stdio.h>

int main()
{    
    int arr[3] = { 1, 2, 3 };    // 建立一个数组。
//    arr 里面存的是数组内存的首地址,而 [] 表示内存里面存的那一堆东西是数组,3 表示数组长度,int 表示数组里面存的数据是 int 类型

    int(*p)[3];    // 长度为 3 的数组指针
    p = arr;
    printf("%d \n", p[1]);

    return 0;
} 
// 数组指针,知识扩展

# include <stdio.h>

typedef int(*pType)[3];    // 定义类型:int(*pType)[3],取别名为:pType

int main()
{    
    int arr[3] = { 1, 2, 3 };
    pType p;    // 变量 p 的类型为 pType,而属于这种类型的变量 p 必然满足 int(*pType)[3] 模板格式
    p = arr;    // arr里面储存的“数组的内存首地址”复制给变量 p
    printf("%d \n", (*p)[0]);    // 注意!不要写成 p[0],虽然 p 获得了 arr 里面存的首地址,但是 *p 才是代表数组整体

    return 0;
} 

/*
    同理:
    # include <stdio.h>

    typeof int pArr[3];

    int main()
    {
        int arr[3] = { 1, 2, 3 };
        pArr p;
        p = arr;
    }
*/

使用const修饰指针

/*
    const:常量,被它修饰的变量会具有常量的属性,使用 const 修饰指针包含三种情况
        1.常量指针(指向常量的指针)
            指向常量的指针 type const *p; 或者 const type *p;
            可以改变指向,但是不能用 *p 修改指向变量的值


        2.指针常量
            它是常量,本身不能改变,也就是不能改变指向
            因为指向不能改,所以必须初始化
            但是可以通过取内容修改指向的内存中的内容


        3.常量指针常量("常量指针"常量即:指针常量)
            指针本身是一个常量,指向的也是常量
            const int * const p = &a;
            不能改变指向,也不能改变指向的内存的内容
*/

# include <stdio.h>

int main()
{
    const int num = 0;    // 变量 num 使用 const 修饰了就不能被修改了
    
    // 1.常量指针
    int a = 0, b = 9;
    const int * p = &a;        // const -> int
    p = &b;    // 可以改变指向


    // 2.指针常量
    int c = 6;
    int* const p1 = &c;        // const -> p1
    *p1 = 10;    // 可以修改内容


    // 3.常量指针常量
    int d = 8;
    const int* const p = &d;    // const -> int 和 p


    return 0;

}

指针和结构体

/*
            指针与结构体:
    指针与结构体结合起来使用包含两种情况:
    一.指针成员
        结构体变量的成员中存在指针

    二.结构体指针
        指向结构体变量的指针
*/
// 指针成员

# include <stdio.h>

typedef struct
{
    int n;
    int m;
    int* p;    // 定义指针

}MyStruct;

int main()
{
    MyStruct mystr;
    mystr.n = 0;
    mystr.m = 0;
    mystr.p = NULL;    // 地址置空
    return 0;

}
// 结构体指针

# include <stdio.h>

typedef struct
{
    int n;
    int m;

}MyStruct;

int main()
{
    MyStruct mystr;
    mystr.n = 0;
    mystr.m = 0;
    
    MyStruct* p = NULL;    // 定义一个指针 p ,它的类型是 MyStruct*,即该指针指向的是有 MyStruct 类型的变量(首地址)
    p = &mystr;    // mystr 便符合条件,可以将首地址 &mystr 赋值给 p

    // 注意!通过指针访问“结构体中的元素”的时候,用 -> 符号,而不是用 . 符号
    p->n = 9;
    p->m = 8;
return 0; }

使用指针的注意事项

/*
    注意事项
        1.避免野指针
            推荐:每次定义指针都进行初始化(有指向就给指向,没指向就置空 )
        2.注意类型匹配
        3.防止内存泄漏
            只有堆区是自己申请,自己释放,其他地方都是系统分配,系统回收

        总结:指针能够直接操作内存,必须在自己明确用途的情况下使用,否则很可能会造成严重后果!
*/

 

posted on 2023-07-15 14:59  -seventy-  阅读(24)  评论(0)    收藏  举报