• 数据结构与算法-----指针与结构体


     目录

    前言

    指针

    定义

    示例1(访问修改数据):

    示例2(野指针):

    示例3(动态空间分配问题):

    示例4(字符串赋值错误问题):

    示例5(空间释放问题):

    结构体

    定义

    结构体指针空间分配


    前言

            今天我们就开始学习数据结构与算法,这是我新开设的一门专栏,接下来我会一边学习数据结构与算法一边去通过csdn来分享我的个人见解与看法,希望各位多多支持!

            这一期的学习内容是C语言的指针与结构体,因为指针结构体是C语言的重要组成部分之一,对后面学习数据结构与算法有重要作用所以我们会从指针结构体去开始学习。之前我们学习过了C语言的相关知识,今天就不过多的去深入文字说明介绍,下面我更多会去通过例子去过一遍这些内容。

    指针

    定义

    数据在内存中的地址也称为指针,如果一个变量存储了一份数据的指针,我们就称它为指针变量

    在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。指针变量的值就是某份数据的地址,这样的一份数据可以是数组、字符串、函数,也可以是另外的一个普通变量或指针变量。

    指针是一个变量,通过指针我们可以去指向一个数据的内存地址,然后去范围里面的数据,通过指针我们可以去操作数据。

    指针变量本身是占有空间的,32位操作系统4个字节,64位操作系统占8个字节

    1. //定义指针变量与定义普通变量非常类似,不过要在变量名前面加星号*,格式为:
    2. datatype *name;

    示例1(访问修改数据):

    1. #include
    2. int main()
    3. {
    4. int* a;
    5. int c=10;
    6. a = &c;
    7. printf("%d %d %d\n", *a, a, c);
    8. //结果:10 8912028 10
    9. *a = 15;
    10. printf("%d %d %d", *a,a,c);
    11. //结果:15 8912028 15
    12. }

    数据的结果被修改了,但是地址并没有改变,这就是指针的基本操作--访问并修改数据

    示例2(野指针):

    1. 指针未被初始化

    2. 指针越界访问

    3. 指针指向的空间释放

    以上是野指针常见的情况

    1. #include
    2. int* test()
    3. {
    4. int a = 10;
    5. printf("%p\n", &a);
    6. return &a;
    7. }
    8. int main()
    9. {
    10. int* p = test();
    11. return 0;
    12. }
    13. //程序开始后首先进入主函数,执行第一步,调用test函数将返回值赋给p, test函数的返回值是局部变量a的地址
    14. //,假设a的地址为0x0093F830, 由于a只在test函数内有效,出了test函数其内存空间就被释放,
    15. //也就意味着a的地址编号不存在,短时间内如果再次利用这块地址,它的值还未被改变也就是0x0093F830还存在,
    16. //p的值为0x0093F830,但此时p为野指针,因为p里面所存放的地址是无效的。

    示例3(动态空间分配问题):

    1. #include
    2. #include
    3. int main()
    4. {
    5. int a = 15;
    6. int* p=(int *)malloc(sizeof(int));
    7. p = &a;
    8. free(p);
    9. }

    很显然,结果会报错的,因为指针p开始指向的是一个动态的空间,而整形a是存放在一个已经分配好了的空间,当让指针p去指向a的地址时候,free(p)时p原本的空间并没有进行释放,而释放的是a的空间,但是a的空间是已经分配好了的,无法释放,这就会导致两个错误,一个是内存泄漏,另一个是空间释放错误。

    示例4(字符串赋值错误问题):

    1. #include
    2. #include
    3. #include
    4. int main()
    5. {
    6. char a[10] ;
    7. char* p=(char *)malloc(sizeof(char)*10);
    8. char* q = (char*)malloc(sizeof(char) * 10);
    9. //1
    10. strcpy(a, "hello");
    11. strcpy(p, "hello");
    12. strcpy(q, "hello");
    13. //2
    14. a = "hello";
    15. p = "hello";
    16. q = "hello";
    17. }

    以上有两种赋值方式,但是第一种才是正确的,第二种是错误赋值。

    示例5(空间释放问题):

    常见问题如下:

    1.忘记释放,内存泄漏

    2.对同一块空间多次释放

    3.对非动态空间释放

    4.部分释放

     部分释放

    1. #include
    2. #include
    3. int main()
    4. {
    5. int* p = (int*)malloc(sizeof(int) * 10);
    6. p++;
    7. free(p); //这里的p的地址并不是起始地址,只是进行了部分的释放
    8. p = NULL;
    9. }

    多次释放

    1. #include
    2. #include
    3. int main()
    4. {
    5. int* p = (int*)malloc(sizeof(int) * 10);
    6. int* q = (int*)malloc(sizeof(int) * 10);
    7. p = q;
    8. free(q);
    9. free(p);
    10. }
    11. //这里p指向了q的地址,下面释放了q,又去释放p,这就会造成多次释放

    结构体

    定义

    C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。

    结构体中的数据成员可以是基本数据类型(如 int、float、char 等),也可以是其他结构体类型、指针类型等。

    声明

    1. struct 结构名{
    2. //成员列表
    3. };
    1. typedef struct {
    2. //成员
    3. }结构体名字;

    以后的话建议用第二种声明方式,这种方式方便我们去命名结构体,容易区分开来。

    结构体指针空间分配

    1. #include
    2. #include
    3. typedef struct {
    4. char* a;
    5. int num;
    6. }Student_data;
    7. int main()
    8. {
    9. Student_data* p=(Student_data*)malloc(sizeof(Student_data));
    10. p->a = (char*)malloc(sizeof(char) * 10);
    11. }

    这里定义了一个结构体指针,实现要对这个结构体指针进行空间分配,其次里面又有一个指针也要进行空间的再次分配,这样才可以去存入数据。

    以上就是本期的全部内容了,主要是大致的过一遍就行了,后面就正式进入数据结构与算法的学习了,我们下一期再见!

    分享一张壁纸:

  • 相关阅读:
    C#通过Entity Framework实体对数据表增删改查
    Unity 实现文字过长显示省略号
    spdk intel
    Mysql开启binlog
    Kotlin文件和类为什么不是一对一关系
    pytorch中使用多GPU并行训练
    性能优化--string 字符串拼接(超详细)
    面向智慧文博的知识图谱构建综述
    git clone和git init git pull 的一点问题
    CSS技巧专栏:一日一例 19 -纯CSS实现超酷的水晶按钮特效
  • 原文地址:https://blog.csdn.net/m0_73633088/article/details/132766850