请选择 进入手机版 | 继续访问电脑版

c语言指针指北

[复制链接]
云韵 发表于 2021-1-2 19:42:27 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
c语言指针简介

稍后增补




案例一

在c语言步调中,可以使用指向字符型数据的指针(char*)表现字符串。

例子如下:
  1. #include int main(int argc, char *argv[]){    char *test = "Hello";    printf("%s\n", test);    printf("%d", sizeof(test));}
复制代码


步调输出效果如下:
  1. Hello8
复制代码

案例二

在使用c语言实现二叉树的根本利用时,也很查验对于指针的利用熟练水平。


本例子使用二叉链表作为二叉树的数据布局。
  1. #include #include typedef char ElemType;typedef struct BinaryTree{    ElemType data;    struct BinaryTree *left_child;    struct BinaryTree *right_child;} BinaryTree;typedef BinaryTree TreeNode;
复制代码

下面是测试步调。
  1. int main(int argc, char *argv[]){    BinaryTree *a, *b, *c, *d, *e, *f, *g;    /* 非内置的数据范例需要手动申请内存空间 */    a = (BinaryTree*)malloc(sizeof(BinaryTree));    b = (BinaryTree*)malloc(sizeof(BinaryTree));    c = (BinaryTree*)malloc(sizeof(BinaryTree));    d = (BinaryTree*)malloc(sizeof(BinaryTree));    e = (BinaryTree*)malloc(sizeof(BinaryTree));    f = (BinaryTree*)malloc(sizeof(BinaryTree));    g = (BinaryTree*)malloc(sizeof(BinaryTree));    a->data = 'A';    a->left_child = b; a->right_child = c;    b->data = 'B';    b->left_child = NULL; b->right_child = NULL;    c->data = 'C';    c->left_child = NULL; c->right_child = NULL;    d->data = 'D';    d->left_child = e; d->right_child = f;    e->data = 'E';    e->left_child = NULL; e->right_child = NULL;    f->data = 'F';    f->left_child = NULL; f->right_child = NULL;    g = a;    printf("将节点a赋值给节点g\n");    printf("节点g的值为 %c\n", g->data);    printf("节点g的左孩子的值为 %c\n", g->left_child->data);    printf("节点g的右孩子的值为 %c\n", g->right_child->data);        return 0;}
复制代码

上述步调构造了一个简朴的二叉树1
  1.                                                 A                                          /   \                                         B           C
复制代码

以及二叉树2
  1.                                                 D                                          /   \                                         E           F
复制代码

以及一个空二叉树G
  1.                                                 G                                          /   \                                        NULL  NULL
复制代码
然后将指针a赋值给指针g。


以上步调的运行效果如下:
  1. 将节点a赋值给节点g节点g的值为 A        节点g的左孩子的值为 B节点g的右孩子的值为 C
复制代码
说明:
将a的地点赋值给g后
a指向的左右孩子也是g指向的左右孩子


接着,再在测试案例中添加一小段代码,看看步调运行过程中虚拟内存的厘革。
  1.         /*         * 在主函数中修改为以下代码         */        printf("利用前\n");    printf("节点a的虚拟内存地点为 %d\n", a);    printf("节点g的虚拟内存地点为 %d\n", g);    g = a;    printf("将节点a赋值给节点g\n");    printf("节点g的值为 %c\n", g->data);    printf("节点g的左孩子的值为 %c\n", g->left_child->data);    printf("节点g的右孩子的值为 %c\n", g->right_child->data);    /*     * 输出效果显示将a的地点赋值给g后     * a指向的左右孩子也是g指向的左右孩子     */    printf("节点a的虚拟内存地点为 %d\n", a);    printf("节点g的虚拟内存地点为 %d\n", g);
复制代码

测试步调运行效果如下:
  1. 利用前节点a的虚拟内存地点为 1394704节点g的虚拟内存地点为 1395184将节点a赋值给节点g节点g的值为 A节点g的左孩子的值为 B节点g的右孩子的值为 C节点a的虚拟内存地点为 1394704节点g的虚拟内存地点为 1394704
复制代码
可以看出,将指针a复制给指针g就是将a的内存地点赋值给g。
因此,a所指向的左右孩子也是g所指向的左右孩子。
接着,再实验使用free()函数释放内存。
再上述代码之后,添加如下代码片断。
  1.         free(g);    printf("free节点g\n");    printf("节点g释放内存后的虚拟内存地点为%d\n", g);    printf("节点g的值为 %d\n", g->data);    printf("节点a的虚拟内存地点为 %d\n", a);    printf("节点a的左孩子的地点原来为(即节点b的地点) %d, 现在为%d\n", b, a->left_child);    printf("节点a的右孩子的地点为 %d\n", a->right_child);
复制代码

运行效果如下:
  1. 利用前节点a的虚拟内存地点为 7817232节点g的虚拟内存地点为 7817712将节点a赋值给节点g节点g的值为 A节点g的左孩子的值为 B节点g的右孩子的值为 C节点a的虚拟内存地点为 7817232节点g的虚拟内存地点为 7817232free节点g节点g释放内存后的虚拟内存地点为7817232节点g的值为 -16节点a的虚拟内存地点为 7817232节点a的左孩子的地点原来为(即节点b的地点) 7817312, 现在为7799120节点a的右孩子的地点为 -17891602
复制代码
可以看出,free(g)但是没有将指针g置为空指针(即令 g = NULL)之后,g的虚拟内存地点稳定,但是g的值厘革为内存块上的随机值。

而且,对指针g释放内存影响到了原先赋值给其的指针a
指针a的虚拟内存地点稳定,(情况和指针g相同)
但是左右孩子的地点跟着被修改。
而且当你试图输出a的左右孩子的值时(如下图)
  1.         printf("节点a的左孩子的值为 %c", a->left_child->data);    printf("节点a的右孩子的值为 %c", a->right_child->data);
复制代码
步调在运行过程中会报错(内存错误)
说明释放指针g的内存时,a的内存也跟着被释放。

原因如下:
指针g和指针a 指向的是同一块地点
所以,在本案例开始的将指针a赋值给g时实在是浅拷贝

如果需要指针g和指针a在拷贝后相互独立,需要使用深拷贝
即将a指向的数据的所有属性逐个赋值给g指向的数据。
别的,若在对指针g举行free()利用后对其赋值为空指针,即
  1.         free(g);    g = NULL;
复制代码
之后的内容与不对其置空根本一致,只是置空之后g的地点为0
由于仍然是浅拷贝,指针a仍然被释放内存,因此效果大部分一致(除了g的地点改变)。

来源:https://blog.csdn.net/Stack_OVER_flow/article/details/112056046
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )