二级指针 订阅
A(即B的地址)是指向指针的指针,称为二级指针,用于存放二级指针的变量称为二级指针变量.根据B的不同情况,二级指针又分为指向指针变量的指针和指向数组的指针。 展开全文
A(即B的地址)是指向指针的指针,称为二级指针,用于存放二级指针的变量称为二级指针变量.根据B的不同情况,二级指针又分为指向指针变量的指针和指向数组的指针。
信息
作    用
为了获取指针的存放地址。
分    类
按指向的数据类型分类
指    针
表现形式是地址
中文名
二级指针
二级指针介绍
首先任何值都有地址 ,一级指针的值虽然是地址,但这个地址做为一个值亦需要空间来存放,是空间就具有地址 ,这就是存放地址这一值的空间所具有的地址,二级指针就是为了获取这个地址。一级指针所关联的是其值(一个地址)名下空间里的数据,这个数据可以是任意类型并做任意用途,但二级指针所关联的数据只有一个类型一个用途,就是地址,指针就是两个用途提供目标的读取或改写, 那么二级指针就是为了提供对于内存地址的读取或改写。指针的表现形式是地址,核心是指向关系指针,运算符“*”的作用是按照指向关系访问所指向的对象.如果存在A指向B的指向关系,则A是B的地址,“*A”表示通过这个指向关系间接访问B.如果B的值也是一个指针,它指向C,则B是C的地址,“*B”表示间接访问C,如果C是整型、实型或者结构体等类型的变量或者是存放这些类型的数据的数组元素,则B(即C的地址)是普通的指针,称为一级指针,用于存放一级指针的变量称为一级指针变量,指向一级指针变量的"A"则是“二级指针”。
收起全文
精华内容
下载资源
问答
  • 二级指针

    千次阅读 2019-07-22 23:10:05
    用于存放二级指针的变量称为二级指针变量.根据B的不同情况,二级指针又分为指向指针变量的指针和指向数组的指针。

      在引入二级指针前,先来看看一个一级指针的算术运算问题:

    int main()
    {
    	//小端电脑
    	int a[] = { 2, 3, 2, 4 };
    	int *ptr1 = (int*)(&a + 1);
    	int *ptr2 = (int*)((int)a + 1);  //这里指向了数组首地址+1的地方
    	printf("0x%x 0x%x\n", ptr1[-1], *ptr2);
    	return 0;
    }
    

      整个代码的输出结果如下所示:
    在这里插入图片描述
      调试的地址和数据信息:
    在这里插入图片描述
      *ptr2的结果分析:
    在这里插入图片描述
      分析总结:
    1.ptr1指向了数组a的倒数第1个数据的存储位置
    2.ptr2指向了数组a首地址+1字节的地方
    3.我的电脑是小端存储

    //测试本机存储是大端还是小端
    union Test
    {
    	int a;
    	char b;
    };
    int main()
    {
    	Test t;
    	t.a = 1;
    	if (t.b == 1)
    		cout << "小端机器" << endl;
    	else
    		cout << "大端机器" << endl;
    	return 0;
    }
    

    在这里插入图片描述
    1.指针问题

    #include <iostream>
    using namespace std;
    
    void getmemery(char* str)
    {
    	*str = (char*)malloc(sizeof(char)*10);
    	memset(*str, 0, sizeof(char)*10);
    }
    
    int main()
    {
    	char* p = NULL;
    	getmemery(p);
    	strcpy(p, "Hello");
    
    	cout <<p << endl;
    }
    

      这一段代码是无法获取到内存的,因为在C语言中函数是按值传递,如果不是传地址,形参的改变是无法影响到实参的。具体可以参考下图:
    在这里插入图片描述
      修改方案一:

    void getmemery(char** str)
    {
    	*str = (char*)malloc(sizeof(char)*10);
    	memset(*str, 0, sizeof(char)*10);
    }
    
    int main()
    {
    	char* p = NULL;
    	getmemery(&p);
    	strcpy(p, "Hello");
    
    	cout <<p << endl;
    	free(p);
    }
    

      要想修改实参的内容,就必须传地址,用二级指针接收,然后解引用。
    在这里插入图片描述
      修改方案二:

    #include <iostream>
    #include<stdlib.h>
    #include<string.h>
    using namespace std;
    
    char* getmemery()
    {
    	char* str = (char*)malloc(sizeof(char)*10);
    	memset(str, 0, sizeof(char)*10);
    	return str;
    }
    
    int main()
    {
    	char* p = NULL;
    	p = getmemery();
    	strcpy(p, "Hello");
    
    	cout <<p << endl;
    	free(p);
    }
    

      这种办法更加安全可靠。

      二级指针在递归中的用法

    BtNode * CreateTree(ElemType **str)
    {
    	BtNode *s = NULL;
    	if(NULL != *str && **str != END)
    	{
    		s = Buynode();
    		s->data = **str;
    		s->leftchild = CreateTree(&++(*str));
    		s->rightchild = CreateTree(&++(*str));
    	}
    	return s;
    }
    
    int main()
    {
    	char* str = "ABC##DE##F##G#H##";
    	BinaryTree root = CreateTree(&str);
    	InOrder(root);
    	return 0;
    }
    

      这里如果不使用传地址,解引用的办法,字符串ABC##DE##F##G#H##是不会递增的,最终建出来的树也不是理想的二叉树,具体如下图所示:
    在这里插入图片描述

      C++的用法

    BtNode * CreateTree(ElemType* &str)
    {
    	BtNode *s = NULL;
    	if(NULL != str && *str != END)
    	{
    		s = Buynode();
    		s->data = *str;
    		s->leftchild = CreateTree(++str);
    		s->rightchild = CreateTree(++str);
    	}
    	return s;
    }
    
    int main()
    {
    	char* str = "ABC##DE##F##G#H##";
    	BinaryTree root = CreateTree(str);
    	InOrder(root);
    	return 0;
    }
    
    展开全文
  • 二级指针的概念 首先任何值都有地址,一级指针的值虽然是地址,但这个地址做为一个值亦需要空间来存放,是空间就具有地址,这就是存放地址这一值的空间所具有的地址,二级指针就是为了获取这个地址,一级指针所关联...
  • 主要介绍了C语言 一级指针与二级指针详细介绍的相关资料,需要的朋友可以参考下
  • 在前面的文章《如何理解C指针及二级指针(1)》 介绍了指针的一些重要概念,对于一级指针,相对来讲是比较容易理解的,这里就不再赘述了。我们重点来看一下二级指针的使用方式。 我们知道,不管是几级 指针,本质...

        在前面的文章《如何理解C指针及二级指针(1)》 介绍了指针的一些重要概念,对于一级指针,相对来讲是比较容易理解的,这里就不再赘述了。我们重点来看一下二级指针的使用方式。

        我们知道,不管是几级 指针,本质上也是个普通变量,只不过指向的内容不同而已。二级指针指向的是“一级指针的地址”。

    这里,参考博友二级指针的详解的里的图片,向作者致谢。

    使用方法一:

       先为二级指针分配空间,然后赋值,解引用采用*。   

        代码段:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]) {
    	int **ptr = NULL;
    	int num = 4, size = 4;
    	int i,j;
    	
    	ptr = (int **)malloc(num * sizeof(int *));
    	for(i = 0; i < num; i++){
    		*(ptr + i) = (int *)malloc(size * sizeof(int));
    		for(j = 0; j < size; j++)
    			*(*(ptr + i) + j) = (i + 1)*j;
    	}
    	
    	for(i = 0; i < num; i++){
    		for(j = 0; j < size; j++){
    			printf("(%d, %d) -> %d\t", i, j, *(*(ptr +i) + j));
    		}
    		printf("\n");
    	} 
    	
    	return 0;
    }

     程序执行结果:

    进一步,通过指针指向图来说明,如下图所示:

     

    使用方法二:

        先为二级指针分配空间,然后赋值,解引用采用数组方式。

    程序代码:

    ptr = (int **)malloc(num * sizeof(int *));
    	for(i = 0; i < num; i++){
    		ptr[i] = (int *)malloc(size * sizeof(int));
    		
    		for(j = 0; j < size; j++)
    			ptr[i][j] = (i + 1)*j;
    	}
    	
    	for(i = 0; i < num; i++){
    		for(j = 0; j < size; j++){
    			printf("[%d, %d] -> %d\t", i, j, ptr[i][j]);
    		}
    		printf("\n");
    	} 

     运行结果:

    在内存中,指针指向图:

    小结:

        我们在使用二级指针时,牢记,二级指针也只是一个普通变量,只不过这个二级指针变量要指向的是一个 指针的地址,理解的时候,一定要先入为主这个概念,这是最根本的定义。

        我们在对指针进行间接引用时,可以使用“*”操作符,也可以使用数组“[ ]”,这说明“*”和“[ ]”的效果是相同的,根据自己的习惯使用就好,我更喜欢使用“[ ]”。

    展开全文
  • 深入理解指针以及二级指针(指针的指针)

    千次阅读 多人点赞 2017-08-11 12:05:43
    前言:本文将讲解指针的定义、指针变量和普通变量的本质区别、一级指针和二级指针的关系以及如何通过二级指针修改一级指针所指向的内存。文末还附加了两个实例,帮助读者加深对二级指针的理解。本文试图通过图表的...

    前言:本文将讲解指针的定义、指针变量和普通变量的本质区别、一级指针和二级指针的关系以及如何通过二级指针修改一级指针所指向的内存。文末还附加了两个实例,帮助读者加深对二级指针的理解。本文试图通过图表的方式,通俗地讲解指针和二级指针,让读者对此有深入的理解。阅读本文大概需要15分钟的时间。

    1、指针的定义:

    int a = 1; //普通变量的定义
    int *pA = &a; //指针的定义
    
    或者
    int *pA = NULL;
    pA = &a;
    

    符号&表示“取址符”,也就是获取上面的变量a所在内存空间的地址。
    从上面指针的第二种定义中就可以看出,变量pA的值等于变量a的内存地址。星号*的作用是表明变量pA是一个指针变量。那么,普通变量和指针变量的区别是什么呢?

    2、普通变量和指针变量

    普通变量:(变量名字name,变量值value,变量的内存地址addr)
    指针变量:(变量名字name,变量值value,变量的内存地址addr)
    

    从表面上看,普通变量和指针变量没有多大区别。实质上的区别是:指针变量的变量值value 存储的是一个用16进制表示的32位内存地址,比如00A6F790。而普通变量的变量值value 所存储的内容没有限制。还有,指针变量能够根据变量值value中的内存地址获取到该地址所对应的值(假设指针变量名为p,通过*p来获取)。具体看下面的关系图:

    这里写图片描述
    其中,上图中变量的定义为:

    int commonVar = 12;
    
    ///
    string str = "hello";
    string * poiterVar = &str;
    

    poiterVar = “00ER343O”
    *poiterVar = “hello”;
    所以,指针变量和普通变量没有太大区别。

    ###3、 一级指针和二级指针的关系

    那么,对于指针的指针呢?

    这里写图片描述
    上图中两个指针的定义为:

    string str = "hello";
    string *poiterVar1 = &str;
    string **poiterVar2 = &poiterVar1;
    

    暂时不要考虑*星号,避免被星号搞混了。星号的作用有两个,一是在指针定义的时候表明该变量是指针变量以及是几级指针(有几个星号就表示几级),二是能够通过指针变量所指向的内存地址(或者说上图中Value的值)来获取对应内存的内容。比如上图中的poiterVar1通过Value = 00ER343O来获取hello,即*poiterVar1

    从上图中还可以看出,一级指针poiterVar1和二级指针poiterVar2没有什么区别。如果非要说出一点区别的话,就是在指针定义的时候,后者多加了一个*星号。

    指针变量修改所指向的内容的时候,因为指针指向的是其内存地址,所以,就相当于把该内存中的内容修改了。这一点是指针强大的原因所在,也是它存在的原因。


    4、实例讲解1

    这里写图片描述
    上图中两个指针的定义为:

    string *poiterVar1 = NULL;
    string **poiterVar2 = &poiterVar1;
    

    指针变量poiterVar1初始化的时候指向了NULL。可以通过poiterVar2修改poiterVar1,让它指向一个非NULL的内容吗? 是可以的。怎么做到呢?
    问题可以转换为:让pointerVar1中的Value等于一个有效的内存地址。具体怎么做呢?因为poiterVar2拥有poiterVar1的内存地址,所以,可以通过poiterVar2来修改poiterVar2变量中的值(也就是它的Value)。具体如下:

    string *poiterVar1 = NULL;
    string **poiterVar2 = &poiterVar1;
    
    string str = "hello";
    
    /*
    if (*poiterVar2 == poiterVar1) 
    	cout << "*poiterVar2 == poiterVar1" << endl;
    else 
    	cout << "*poiterVar2 != poiterVar1" << endl;
    */
    
    *poiterVar2 = &str;
    
    cout << *poiterVar1 << endl;
    
    //执行结果
    //*poiterVar2 == poiterVar1
    //hello
    

    上面代码中,*poiterVar2 代表poiterVar1的Value,把str的内存地址赋值给*poiterVar2 就可以了。


    5、实例讲解2

    本实例和第一个实例基本相同,只是把string类型变成了自定义的Teacher类型。开始的时候Teacher类型的指针为NULL,通过一个二级指针让一级指针指向一个有效的内存空间。也是指针的指针的问题,一级指针是teacherObj,二级指针是pTeacher(函数的参数)。
    这里写图片描述

    在代码中它们的关系可以表示为:

    Teacher *teacherObj = NULL;
    Teacher **pTeacher = &teacherObj;
    

    所以,这个实例和第一个实例是一样的。

    #include <iostream>
    #include <string>
    using namespace std;
    
    struct Teacher {
    	int age;
    	char* name;
    };
    
    int getTeacher(Teacher **pTeacher){
    	if (pTeacher == nullptr)return -1;
    	Teacher * tmpTeacher = (Teacher*)malloc(sizeof(Teacher));
    	if (tmpTeacher == nullptr) return -1;
    	tmpTeacher->age = 32;
    	tmpTeacher->name = "Liangyihuai";
    	*pTeacher = tmpTeacher; //*pTeacher就代表一级指针的value值。
    	return 1;
    }
    
    int main() {
    
    	Teacher *teacherObj = NULL;
    	
    	getTeacher(&teacherObj);
    
    	cout << teacherObj->age << " " << teacherObj->name << endl;
    
    	system("pause");
    	return 0;
    }
    

    拓展:
    上面的getTeacher方法也可以写成:

    int getTeacher2(Teacher* &pTeacher) {
    	Teacher * tmpTeacher = (Teacher*)malloc(sizeof(Teacher));
    	if (tmpTeacher == nullptr)return -1;
    	tmpTeacher->age = 32;
    	tmpTeacher->name = "Liangyihuai";
    	pTeacher = tmpTeacher;
    	return 1;
    }
    
    //在main函数中:
    //Teacher *teacherObj = NULL;
    //getTeacher2(teacherObj);
    

    其中引用pTeacher表示teacherObj,也就是pTeacher是teacherObj的一个别名,而teacherObj是一个指针变量,所以,让pTeacher等于一个有效的内存空间就可以了。

    6、总结:

    本文讲解了指针变量和普通变量的区别。分析了二级指针和一级指针的区别和本质,以及如何使用二级指针修改一级指针所指向的内存空间。如果有误,欢迎指教。

    展开全文
  • 首先几个概念: 一级指针: int a; int *p; p = &a; &p//指针所在内存的地址 p//指针p的值,也就是所指向内存区的地址...二级指针: int **q; q = &p//q指向一个指针 &q//指针q所在内存区的地址 q

    首先几个概念:
    一级指针:
    int a;
    int *p;
    p = &a;
    &p//指针所在内存的地址
    p//指针p的值,也就是所指向内存区的地址(a的地址)
    *p//p所指向内存区内的值(a的值)
    二级指针:
    int **q;
    q = &p//q指向一个指针
    &q//指针q所在内存区的地址
    q//指针q的值,也就是p所在内存区的地址,等同于&p
    *q//指针q所指向内存的值,也即是指针p的值,等同于p(a的地址)
    **q//a的值
    那为什么非要引入二级指针呢
    先看一个例子:

    #include<iostream>
    using namespace std;
    int a = 2, b = 3;
    int * q;
    void fun(int *p)
    {
        p = &b;
        //*p = b;
    }
    int main()
    {
        q = &a;
        cout << *q << endl;
        fun(q);
        cout << *q << endl;
        return 0;
    }

    结果:
    2
    2
    将指针作为参数传递,传入的是实参的拷贝,所以指针p和指针q指向的同一个内存,若在函数内改变p的指向,并不影响q。。。所以p指向的值并未改变。
    当然若通过*p改变p所指向的内容,则q的指向也没变。。只不过指向的内存改变了。

    再看使用二级指针的情况

    #include<iostream>
    using namespace std;
    int a = 2, b = 3;
    int * q;
    void fun2(int **p)
    {
        *p = &b;
    }
    int main2()
    {
        q = &a;
        cout << *q << endl;
        fun2(&q);
        cout << *q << endl;
        return 0;
    }

    结果:
    2
    3
    调用结束后指针q从指向a变成了指向b。
    总结:
    二级指针的引入是为了能够在函数调用的过程中保持对传入指针的改变。。即改变传入指针的指向。。

    例如一个经常用到的场合

    #include <iostream>
    using namespace std;
    void GetMeory(char **p, int num)
    {
     *p = (char *)malloc(sizeof(char) * num);//malloc返回一个void *
     //*p = new char[num];  //C++当中
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
     char *str = NULL;
     GetMeory(&str, 100);
     strcpy(str,"Hello");
     cout << str << endl;
     return 0;
    }

    通过二级指针在函数内为外部指针分配内存

    展开全文
  • 二维数据_指针_二级指针
  • 对于二叉树的创建,令我疑惑不解的是用二级指针的操作,会有很多关于指针的操作,但是用二级指针的原因总结起来就是函数的调用是值传递,所以用一级指针需要返回值,而用二级指针不需要返回值. 接下来用代码直观的表示...
  • 只有6行代码,非常简洁,这是char二级指针给char二维数组赋值的逻辑。二级指针需要先赋值操作,加断点就可以看见二维数组里的值了。
  • 主要介绍了C语言中二级指针的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握理解二级指针的知识,需要的朋友可以参考下
  • 主要介绍了C语言中的指针以及二级指针代码详解,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
  • 本文主要介绍C语言 二级指针,这里整理了C语言中二级指针的基础资料并附有示例代码和实现结果,帮助大家学习理解相关知识,有学习的朋友可以参考下
  • 02 二级指针.pdf

    2021-09-14 09:49:45
    02 二级指针.pdf
  • 二级指针和多级指针

    千次阅读 2019-02-07 09:38:17
    二级指针与多级指针: int i=1; int *p1=&amp;amp;i; int **p2=&amp;amp;p1; int ***p3=&amp;amp;p2; 一级指针: 指针变量p1的类型为int*,所指向的类型为int,储存的值为int类型变量i的首地址,即...
  • C++ 一级指针和二级指针

    千次阅读 2017-03-09 09:35:51
    一级指针就是指指针,就是内存地址,二级指针就是指向指针的指针,就是地址的地址:打个比方,你有一个箱子A(相当于代码中的变量a),里面有你要的东西(值4),你的钥匙1(相当于一级指针p)能打开箱子A,这把钥匙就是一...
  • 我想不大理解二级指针的根源是我对程序对堆栈的用法还不够深入了解。 采用一级指针最好是方便修改指针对象的值,采用二级指针最好是方便修改指针的值。#include #include using namespace std;class haha { }; ...
  • Linux C 指针数组与二维数组 数组指针与二级指针.pdf
  • 二级指针内存模型.zip

    2019-11-20 11:08:38
    二级指针简单内存模型,在堆区maollc分配内存,free释放内存。将申请内存空间、释放内存空间、排序、打印接口进行了封装。
  • C语言——二级指针.pdf
  • 二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {abc, def, ghi}; 这种模型为二级指针的...
  • c++二级指针和一级指针

    千次阅读 2019-06-16 16:17:42
    对于指针,大家都不陌生,最常见的...这是一个简单的例子,题中,指针p存放的是a的地址,二级指针q指向变量p,即q存放的是p的地址,所以对q解一次引用得到的是变量p,即a的地址,解两次引用相当于对p解引用得到变量a...
  • 在用c/c++写数据结构程序时,链表和二叉树中经常需要用到二级指针或者一级指针的引用,那么什么时候用什么时候不用呢? 先看一个简单的c++链表操作程序: (虽然风格有点像c,不过这个是cpp文件,不要在意这些细节...
  • 对于二维数组 二级指针以及数组指针的讨论。对于二维数组 二级指针以及数组指针的讨论

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 280,042
精华内容 112,016
关键字:

二级指针