朋也的博客 » 首页 » 文章

C/C++ 指针,堆,栈总结

作者:朋也
日期:2021-10-12
类别:C学习笔记 


版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证

*& 的区别

*可被用来声明指针,也可被用来获取指针指向地址的值

#include <stdio.h>
int main() {
    int a = 10;
    int *b = &a;

    printf("a = %d b = %p *b = %d\n", a, b, *b);

    return 0;
}

输出

a = 10 b = 000000000065FE14 *b = 10

& 被用来获取内存的地址,比如上面例子中,int *b = &a; 就是将a变量的地址赋值给指针b

结构体

在C中没有对象的概念,但有个结构体,可以被用来封装对象,用法如下

#include <stdio.h>
#include <string.h>

struct user {
    char name[5]; // 必须要带上长度
    int age;
};

int main() {
    struct user user_1 = {"java", 24};
    printf("name = %s age = %d\n", user_1.name, user_1.age);

    struct user *user_2 = &user_1;
    strcpy(user_2->name, "C"); // 给char[]赋新值
    user_2->age = 25;
    printf("name = %s age = %d\n", user_2->name, user_2->age); // 取指针指向数据的值本来使用的是 (*user_2).name 这里使用 -> 简化了写法

    return 0;
}

方法间传值

如果想在调用方法时,还想使用当前作用域的数据且能同步更新的话,就需要传内存地址

如下,如果只传值的话,在方法 swap()中即使调换了数据,回到main里打印也不会生效

#include <stdio.h>

// 在方法swap里定义了两个int变量,这两个int变量的作用域就只在方法 swap()里,在main里调用了这个方法并传入了main中的ab,相当于使用main中的ab变量给swap方法中的ab形参初始化了,所以在swap里将ab调换仅仅修改的是swap方法下的ab,并没有对main中的ab进行值调换
void swap(int a, int b) {
    int tmp = a;
    a = b;
    b = tmp;
}

int main() {
    int a = 1, b = 2;
    swap(a, b);

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

    return 0;
}

如果传内存地址的话,就能解决了

#include <stdio.h>

void swap(int *a, int *b) {
    // 通过 * 来获取内存地址指向数据的值,然后进行交换操作
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

int main() {
    int a = 1, b = 2;
    swap(&a, &b); // 传内存地址过去

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

    return 0;
}

数组

C中数组没有越界异常,声明一个 char name[10]; 然后给它初始化,可以初始化成超过10位,超出部分会在内存里找下一个或者下几个char类型的地址然后进行赋值,这是非常可怕的

栈与堆

栈案例

#include <stdio.h>

int main() {
    int a = 1, b = 2;

    {
        int c = 3; // 程序走到这地方时,会创建一个c变量然后将其压入栈中
    }

    // 当上面代码块执行完时,里面的变量的生命周期也就结束了,会自动被系统给清除掉,所以在下面printf里打印c会报错
    printf("a = %d b = %d c = %d\n", a, b, c);

    return 0;
}

堆案例

#include <stdio.h>
#include <stdlib.h>

int main() {
    int a = 1, b = 2;

    int *c; // 声明一个野指针
    {
        c = (int *)malloc(sizeof(int)); // 给指针分配一块内存空间,此时这个变量是被放在堆里管理的,大小就是int的默认长度
        *c = 3; //给指针c赋值
    }

    printf("a = %d b = %d c = %d\n", a, b, *c);// 打印
    free(c); //释放内存,如果不手动释放,就一直在内存里存在

    return 0;
}