注册 登录
编程论坛 C语言论坛

请问怎么理解二级指针和一级指针呢,新手求教

叶纤 发布于 2020-03-31 11:57, 7635 次点击
程序代码:

#include<stdio.h>
int main()
{
int value = 5;

 
int *ptr = &value;
printf ("%d",*ptr);

 
int **ptrptr = &ptr;
printf ("%d",**ptrptr);
}

41 回复
#2
lin51616782020-03-31 12:40
理解对象指针就可以了 不用特意区分一级二级
理解对象指针只需要注意2个方面
一个是一元&运算和一元*运算
另一个是指针算术
其他的也就强制类型转换做一些骚操作 和 一点生存期的问题
注意这些东西都和类型挂钩
指针的全部内容就这样了
#3
lin51616782020-03-31 12:43
至于汇编呀 寻值啊这些东西对理解指针倒是关系不大
懂了没多大帮助
不懂没多什么影响

注意 这个评论仅针对理解指针
汇编在其他方面有重要意义
#4
叶纤2020-03-31 13:28
理解对象指针就可以了
解对象指针只需要注意2个方面
一个是一元&运算和一元*运算
另一个是指针算术

从这句话中成功的让我产生了3点疑问
1,对象指针是什么
2,一元&和一元*是什么,这个可以查资料
3,关于指针算数,目前我知道的是数组,还有迭代器好像有这个指针算数,那和二级指针有什么关联呢?
其他的也就强制类型转换做一些骚操作 和 一点生存期的问题

这一句话有4点疑问
1指针强制类型转换?
2。指针里面装的不是地址吗?
3地址也分类型吗?
4地址可以进行类型转换吗?

#5
lin51616782020-03-31 13:42
以下是引用叶纤在2020-3-31 13:28:16的发言:

理解对象指针就可以了
解对象指针只需要注意2个方面
一个是一元&运算和一元*运算
另一个是指针算术
从这句话中成功的让我产生了3点疑问
1,对象指针是什么
2,一元&和一元*是什么,这个可以查资料
3,关于指针算数,目前我知道的是数组,还有迭代器好像有这个指针算数,那和二级指针有什么关联呢?

这一句话有4点疑问
1指针强制类型转换?
2。指针里面装的不是地址吗?
3地址也分类型吗?
4地址可以进行类型转换吗?

指针分两种 对象指针 函数指针 这样说就应该明白对象指针是什么了 除了函数指针 剩下的都是对象指针
指针算术 指的是
指针 + 整型
指针 - 整型
指针 - 指针
++/--指针
指针++/--
等操作

我说的不是理解一级指针 二级指针 我说的是 理解全部对象指针

强制类型转换的语法要求是
标量类型转换到标量类型
任何类型转换到void
指针强制类型转换属于 标量类型转换到标量类型
指针当然可以做强制类型转换

指针变量装的是指针而不是地址
指针是一个语法层的概念 指针的主要内容也全部集中在语法上的操作 主要涉及到类型信息
地址是汇编层的概念 指针不是地址

地址不分类型

类型转换是一个语法机制 地址不属于语法的内容
谈不上对地址进行类型转换
#6
叶纤2020-03-31 14:19
越来越糊涂了,我没想那么复杂,就是想知道二级指针应该怎么理解,,
#7
叶纤2020-03-31 14:21
算了,我先自己摸索摸索吧,然后再和您探讨二级指针的运算和类型转换问题
#8
lin51616782020-03-31 14:23
回复 5楼 lin5161678
理解 二级指针的 一元&和一元* 和 指针算术 就完事了
我这段话就这样的意思
怎么会理解不了呢
#9
自学的数学2020-03-31 14:28
p1:指针变量名
*p1:访问p1指向的变量
p2:二级指针变量【指向一级指针,保存的是一级指针变量的内存地址】
*p2:获取一级指针的值【即一级指针指向的变量的内存地址】
**p2:获取一级指针指向的变量的值
输出p2得到的是一级指针变量的地址
输出*p2得到的是一级指针变量指向的普通变量的地址
输出**p2得到的是一级指针变量指向的普通变量的值
#10
叶纤2020-03-31 14:28
可是我不知道什么是二级指针?对二级指针不理解,又怎么会理解二级指针的一元&和一元*的指针算术呢
学猪跑,起码要知道猪长什么样子吧,还要知道猪怎么跑的吧
#11
lin51616782020-03-31 14:35
以下是引用叶纤在2020-3-31 14:28:47的发言:

可是我不知道什么是二级指针?对二级指针不理解,又怎么会理解二级指针的一元&和一元*的指针算术呢
学猪跑,起码要知道猪长什么样子吧,还要知道猪怎么跑的吧

和一级指针没什么区别 从类型A派生的一个指针类型
只是这个类型A 也是一个指针类型而已
知道什么是一级指针而不懂什么是二级指针的情况是不存在的
#12
叶纤2020-03-31 14:49
好好好,我就是那个,只懂一级指针不懂二级指针的猪猪,行了吧
#13
lin51616782020-03-31 14:52
回复 12楼 叶纤
那么 你描述一下 一级指针的 一元&操作和一元*操作 和 指针算术
比如 int*
#14
自学的数学2020-03-31 15:31
一级指针就是指指针,就是内存地址,二级指针就是指向指针的指针,就是地址的地址,打个比方,你有一个箱子,里面有你要的东西,你的钥匙能打开箱子,钥匙就是一级指针,你要用钥匙打开别的箱子去拿到开你要的东西的箱子的钥,那你手上的钥匙就是二级指针,如此类推…
#15
lin51616782020-03-31 15:53
回复 14楼 自学的数学
这样的描述 就不谈对不对吧
对指针的使用没什么帮助
#16
叶纤2020-03-31 16:20
以下是引用lin5161678在2020-3-31 14:52:22的发言:

那么 你描述一下 一级指针的 一元&操作和一元*操作 和 指针算术
比如 int*

我不懂什么是一元二元的
&符号目前我知道有三种意思
1,位运算的和运算符英文是bit-and
2,是引用符号
3,是取地址符号
*目前我知道三种
1,乘法符号
2,指针符号
3,解引用符号
关于一级指针,用的最多的是指针运算符,取地址运算符和取消引用运算符
 在定义一个变量的时候会分配一个空闲地址,然后变量的任何值会存在地址中
程序代码:
#include <iostream>
using namespace std;
int main()
{
    int num=4;
    cout<<&num<<"    ";
    int * p=&num;
    cout<<*p;

}

cout<<&num<<"   

从上面的例子看,使用了取地址符号看见了分配变量的地址
int * p=&num;

p是指向一个int类型的指针,p里装的是num的指针,num通过取地址符,返回一个带有值地址的指针,p接收num的地址
cout<<*p;

此地为解引用符号,取消引用访问特定地址的值
指针算数
我目前只知道数组啊,还有迭代器,本人基础差,还需要学习的更多,
程序代码:
#include <iostream>
#include<vector>
using namespace std;
void arraynum()
{  vector <int>myarray{1,2,3,4};
myarray.resize(5);
cout<<&myarray[0]<<"  ";
cout<<&myarray[1]<<"  ";
cout<<&myarray[2]<<"  ";
cout<<&myarray[3]<<"  ";
cout<<&myarray[4]<<"  ";

}
int main()
{
    int num=4;
    cout<<&num<<"    ";
    int * p=&num;
    auto tex1= p+1;
    auto tex2=p+2;
    auto tex3=p+3;
    cout<<tex1<<"  ";
    cout<<tex2;
    arraynum();
}

从上面可以看见,p+1,+2,+3..表示加了多少类型字节数,int型的
p+3,表示地址加了3个整数12个字节,
如果用在数组上表示数组第几个元素的地址,使用解引用符号就可以看见里面的值*(myarray+1)
#17
lin51616782020-03-31 16:42
回复 16楼 叶纤
全部再加一个 *
就是二级指针了 是不是很简单
#18
lin51616782020-03-31 16:43
回复 16楼 叶纤
比如这句话
p+1,+2,+3..表示加了多少类型字节数,int型的

换成p换成二级指针 就也只是
p+1,+2,+3..表示加了多少类型字节数,int*型的

#19
lin51616782020-03-31 17:00
一元二元就是操作数的个数
1+2
+运算符 左右各有1个操作数 这个叫做二元+运算符
-2
-运算符 只有右边1个操作数 这个叫做一元-运算符

同样
&n
只有右边1个操作数 叫做一元&运算符

之所以要强调是一元的原因你也说了
&符号同时还是位运算 不过 位运算 1&2 是一个二元运算符
强调是 一元& 就能排除掉&作为位运算的情况 特指&作为取指针运算符
#20
叶纤2020-03-31 17:55
不可以
程序代码:

#include <iostream>
#include<vector>
using namespace std;
void arraynum()
{  vector <int>myarray{1,2,3,4};
myarray.resize(5);
cout<<&myarray[0]<<"  ";
cout<<&myarray[1]<<"  ";
cout<<&myarray[2]<<"  ";
cout<<&myarray[3]<<"  ";
cout<<&myarray[4]<<"  ";

}
int main()
{
    int num=4;
    cout<<&num<<"    ";
     int **p=&num;//这里报错
    auto tex1= p+1;
    auto tex2=p+2;
    auto tex3=p+3;
    cout<<tex1<<"  ";
    cout<<tex2;
    arraynum();
}

#21
lin51616782020-03-31 18:03
以下是引用叶纤在2020-3-31 17:55:20的发言:

不可以
#include <iostream>
#include<vector>
using namespace std;
void arraynum()
{  vector <int>myarray{1,2,3,4};
myarray.resize(5);
cout<<&myarray[0]<<"  ";
cout<<&myarray[1]<<"  ";
cout<<&myarray[2]<<"  ";
cout<<&myarray[3]<<"  ";
cout<<&myarray[4]<<"  ";

}
int main()
{
    int num=4;
    cout<<&num<<"    ";
     int **p=#//这里报错
    auto tex1= p+1;
    auto tex2=p+2;
    auto tex3=p+3;
    cout<<tex1<<"  ";
    cout<<tex2;
    arraynum();
}

全部加一个*
你对全部有什么误解
既然 p 你加了 *
num也得加*
#22
叶纤2020-03-31 18:10
     int **p=&*num;
这样?
int **p=&**num;这样?哪样?
#23
lin51616782020-03-31 18:13
#include <iostream>
using namespace std;
int main()
{
    int* num;
    int** p=&num;
}
int ** p=&num;
p是指向一个int*类型的指针,p里装的是num的指针,num通过取地址符,返回一个带有值地址的指针,p接收num的地址
#24
你们都要疼我哦2020-03-31 18:20
  指针的问题还是很重要的,记得数据结构里要大量用到。
另外,要深刻理解指针,必定绕不开地址。本身C和C++就靠底层。尤其
是C,不谈地址光讲指针,纯属臆想。
#25
lin51616782020-03-31 18:27
回复 24楼 你们都要疼我哦
指针用得足够多 就能明白 地址根本无关紧要
#26
wmf20142020-03-31 18:34
我肯定是落伍了,不和现在的小年轻在一个次元。
以我低次元的理解:一开始讨论就偏航了,一个问二级指针的问题怎么就和类扯上关系了?要知道,c在用二级指针里鼓捣来鼓捣去时,面向对象的类还没出现呢。
我觉得:1,不管几级指针,你把它当做一个变量就可以了,只是这个变量值是一个内存地址值,不是你们通常理解的用于四则运算的数(其实也是一个数)
        2,*运算符作为单目(好像是你们讨论中所说的一元二元,我落伍了,我只有单目、双目、三目运算符的概念,今天学习了)运算符时就是取出该变量的值,再把该值作为地址,取出该值指向的内存变量值,通俗地说就是间址寻址,有两个*号就间址寻址两次,有n个就n次。
        3,指针类型是针对编译器的,根据类型编译器决定在指针运算时移动的尺寸,在汇编语言里,指针是没有这个概念的,你inc bp(相当于p++)一次,这个指针寄存器的值就只加一。
        4,好多教科书把二级指针对应为二维数组,这让我在实际写代码时迷茫了一会,实际上你根本不能像一维数组那样把二维数组的首地址传给一个二维指针,除非你是用*p[]的方式定义的。
        5,我最早会写代码,只会汇编、basic,教科书有fortran,都是一些上古语言。14年才开始决心学会写c代码,那时我就觉得c和汇编最相近,并且指针就是对应汇编里的间址寻址,所以自觉理解指针不难(今天看了各位的讨论,才知道我对指针完全没有理解)。实际上,随着编程语言越来越高级,指针已经不再是写代码所必须掌握的了。
        6,我以上的理解肯定是错误的,以其他大神的说法为准,只希望楼主不要走我错误路线。
#27
lin51616782020-03-31 18:52
以下是引用wmf2014在2020-3-31 18:34:23的发言:

我肯定是落伍了,不和现在的小年轻在一个次元。
以我低次元的理解:一开始讨论就偏航了,一个问二级指针的问题怎么就和类扯上关系了?要知道,c在用二级指针里鼓捣来鼓捣去时,面向对象的类还没出现呢。
我觉得:1,不管几级指针,你把它当做一个变量就可以了,只是这个变量值是一个内存地址值,不是你们通常理解的用于四则运算的数(其实也是一个数)
        2,*运算符作为单目(好像是你们讨论中所说的一元二元,我落伍了,我只有单目、双目、三目运算符的概念,今天学习了)运算符时就是取出该变量的值,再把该值作为地址,取出该值指向的内存变量值,通俗地说就是间址寻址,有两个*号就间址寻址两次,有n个就n次。
        3,指针类型是针对编译器的,根据类型编译器决定在指针运算时移动的尺寸,在汇编语言里,指针是没有这个概念的,你inc bp(相当于p++)一次,这个指针寄存器的值就只加一。
        4,好多教科书把二级指针对应为二维数组,这让我在实际写代码时迷茫了一会,实际上你根本不能像一维数组那样把二维数组的首地址传给一个二维指针,除非你是用*p[]的方式定义的。
        5,我最早会写代码,只会汇编、basic,教科书有fortran,都是一些上古语言。14年才开始决心学会写c代码,那时我就觉得c和汇编最相近,并且指针就是对应汇编里的间址寻址,所以自觉理解指针不难(今天看了各位的讨论,才知道我对指针完全没有理解)。实际上,随着编程语言越来越高级,指针已经不再是写代码所必须掌握的了。
        6,我以上的理解肯定是错误的,以其他大神的说法为准,只希望楼主不要走我错误路线。

本来就没有一个人谈到类 这里回帖你是第一个提到类的人了
指针完整概念应该理解为类型 基于某个完整类型的派生类型
为什么不能理解为变量呢 举个例子 (void*)0是指针表达式 却不是变量
一元二元
一目二目这个只是同义词 一个意思
百度一下一目运算符和一元运算符 找到的内容是一样的
喜欢用哪个词就用那个 无所谓

纠正 突然想起来 不完整类型也可以派生指针
基于某个完整类型的派生类型 一句话说错
应该是继续某个类型的派生类型

比较有意义的是 因为派生类型本身也是一个类型
所以这个概念是递归的
基于int 派生int*类型
基于int* 派生int**类型
可以继续下去
限制派生层次的只有编译器实现了 233

[此贴子已经被作者于2020-3-31 20:09编辑过]

#28
wmf20142020-03-31 19:01
回复 27楼 lin5161678
我说过我可能在另外一个时空,有理解障碍。
理解对象指针就可以了 不用特意区分一级二级理解对象指针只需要注意2个方面”,这是你在二楼的原话,我肯定理解错了,我的理解是:理解对象指针就可以了 不用特意区分一级二级...,我就觉得:对象不是类里的术语吗,所以就误以为你们在谈类了。见笑了。

对了,派生也是类里的概念,我觉得,你谈到这些术语时,如果不是原意思,就特别指出下,我脑子转不赢,爱混淆。

[此贴子已经被作者于2020-3-31 19:04编辑过]

#29
lin51616782020-03-31 19:03
以下是引用wmf2014在2020-3-31 19:01:03的发言:

我说过我可能在另外一个时空,有理解障碍。
“理解对象指针就可以了 不用特意区分一级二级理解对象指针只需要注意2个方面”,这是你在二楼的原话,我肯定理解错了,我的理解是:理解对象,指针就可以了 不用特意区分一级二级...,我就觉得:对象不是类里的术语吗,所以就误以为你们在谈类了。见笑了。

答对了 你的确理解错了
你从断句开始就理解错
我说的是 对象指针 这是一个完整的词
理解 对象指针 就可以了 不用特意区分一级二级
#30
lin51616782020-03-31 19:05
回复 28楼 wmf2014
至于什么是 对象指针 我在5楼的回复中也做了解释
指针分2种 对象指针和函数指针
#31
wmf20142020-03-31 19:10
回复 29楼 lin5161678
28楼回答有所修改,怕你没看见,特意再回复下:“指针完整概念应该理解为类型 基于某个完整类型的派生类型”,这是你27楼的话,派生也是类里的概念,我觉得,你谈到这些术语时,如果不是原意思,就特别指出下,我脑子转不赢,爱混淆,我相信初学者也会和我一样迷糊。
#32
lin51616782020-03-31 19:36
以下是引用wmf2014在2020-3-31 19:10:00的发言:

28楼回答有所修改,怕你没看见,特意再回复下:“指针完整概念应该理解为类型 基于某个完整类型的派生类型”,这是你27楼的话,派生也是类里的概念,我觉得,你谈到这些术语时,如果不是原意思,就特别指出下,我脑子转不赢,爱混淆,我相信初学者也会和我一样迷糊。

基础概念缺失太大
首先明确一下 c有对象的概念 并且这个概念和面向对象无关
https://zh.
他的原文就是object我也没什么办法
同样c也有派生类型的概念 和继承没有关系
https://zh.
没有所谓原意思 词太少 不同环境适配不同语意
我讲c 自然使用c原生态术语
我不知道这有什么错
#33
lin51616782020-03-31 19:41
以下是引用wmf2014在2020-3-31 19:10:00的发言:

28楼回答有所修改,怕你没看见,特意再回复下:“指针完整概念应该理解为类型 基于某个完整类型的派生类型”,这是你27楼的话,派生也是类里的概念,我觉得,你谈到这些术语时,如果不是原意思,就特别指出下,我脑子转不赢,爱混淆,我相信初学者也会和我一样迷糊。

有回帖的热情可以理解,但还是要深思熟虑
原话还给你了
再送你一句 遇到看不懂的内容应该多查查资料
既然你理解的派生是类的概念 而我没讲类
你在认为我说错之前 应该先确认一下是不是自己资料看少了
#34
tcxk2020-03-31 19:45
。。。这个。。。有点晕啊,听着你们互相引用,我倒是迷糊了
#35
lin51616782020-03-31 19:53
以下是引用tcxk在2020-3-31 19:45:16的发言:

。。。这个。。。有点晕啊,听着你们互相引用,我倒是迷糊了

这个呀
理解指针类型 主要内容是一元& 和 一元* 和 指针算术
就差不多了

其他的 强制类型转换
const加指针这个用处不大又繁琐
有兴趣就了解了解

这帖子的内容大概是这样了

至于我和他相互回帖没什么干货 可以忽略
#36
return_02020-03-31 20:07
指针真是一个复杂的东西,指针指针,归根结底就是指向某一个位置,确切的说,是地址。
#37
lin51616782020-03-31 20:15
以下是引用return_0在2020-3-31 20:07:15的发言:

指针真是一个复杂的东西,指针指针,归根结底就是指向某一个位置,确切的说,是地址。

我看来指针倒是挺简单的
掌握c的类型系统 知道一元&一元* 和指针算术
就基本完事了
90%以上的指针使用都只在这个范围打转
#38
叶纤2020-03-31 20:52
刚刚查了资料,;理解了一些,发现除了指向类型对象的指针还有很多,比如函数指针,指向成员的指针,指向类对象的指针,直线常量对象的指针,指向成员函数的指针,viod指针,等等等,二级指针这么偏新手的东西我居然理解的那么吃力,不过从我刚看的资料,和通过您们的知识讨论中,我好像理解一些了,倒着想指针就比较简单了,
    int*a;
比如 int**p=&a;
是指向int*指针,那么指针标识符也应该是接收的是int*类型的, 其他的需要自己慢慢消化呀,路上还是需要您们的陪伴呀
感谢有您们
#39
lin51616782020-03-31 21:05
以下是引用叶纤在2020-3-31 20:52:10的发言:

刚刚查了资料,;理解了一些,发现除了指向类型对象的指针还有很多,比如函数指针,指向成员的指针,指向类对象的指针,直线常量对象的指针,指向成员函数的指针,viod指针,等等等,二级指针这么偏新手的东西我居然理解的那么吃力,不过从我刚看的资料,和通过您们的知识讨论中,我好像理解一些了,倒着想指针就比较简单了,
    int*a;
比如 int**p=&a;
是指向int*指针,那么指针标识符也应该是接收的是int*类型的, 其他的需要自己慢慢消化呀,路上还是需要您们的陪伴呀
感谢有您们

函数指针 因为和一级指针二级指针这些东西关系不大 所以就一句话扫过去
指向成员的指针 C没有 如果你指定是指向结构体类型 那也只是普通指针
直线常量对象的指针 我在35楼的回复提到了 用处不大但繁琐 有兴趣就了解了解
指向成员函数的指针 C没成员函数的概念
void* 指针也是对象指针 不过的确有特殊之处 值得单独讨论
不能* 不能做指针算术
讨论完了
#40
叶纤2020-03-31 21:10
回复 39楼 lin5161678
没事,没事,c里没有没事的,c++里面有就行了
#41
你们都要疼我哦2020-04-01 02:33
看来真是落后了,现在已经没有构造类型的说法了,果然变成了派生类型。

[此贴子已经被作者于2020-4-1 04:49编辑过]

#42
lin51616782020-04-01 07:51
以下是引用你们都要疼我哦在2020-4-1 02:33:54的发言:

看来真是落后了,现在已经没有构造类型的说法了,果然变成了派生类型。

在无关紧要的同义词上面死磕 这是书呆子的行为
好啦好啦 知道派生类型也可以写成构造类型了
1