从计算机底层认识指针!深入理解C语言指针!

แชร์
ฝัง

ความคิดเห็น • 117

  • @victorzhao2769
    @victorzhao2769 ปีที่แล้ว +4

    好极了!简单明了,易懂。 提建议:最好能尽可能在每一个专业术语后都加上英语,这样能帮助学习者增强读英语专业文章的技能。计算机毕竟是英语国家开始的,中国学者必须要提高英语直接阅读的技能,才能更快提升专业技能水平,尤其对专业术语英语的掌握,是第一步,最重要的一步。

  • @Chairmao
    @Chairmao ปีที่แล้ว +1

    这个频道太厉害了,这么多视频,够我看几年了。最近正在学习单片机,发现这个频道,非常开心

  • @cheneymx
    @cheneymx ปีที่แล้ว +26

    说的真好! 从来没有这么仔细想过底层实现.

    • @czwbtyzwb
      @czwbtyzwb ปีที่แล้ว +1

      如果你学了计算机组成原理,这些都是自然而然的事

    • @m0923678421
      @m0923678421 ปีที่แล้ว

      @@czwbtyzwb 那我可能不自然,老師都沒像這位YT說這麼清楚好懂,我的教授只會照本宣科,叫我們背起來....就是背....,當時專題使用8051,就是因為指標一直不懂,有些功能沒有實現,下課跑去問教授還被打槍,希望那位教授不要在學校內搞壞學弟學妹的求知慾,太可悲了

    • @czwbtyzwb
      @czwbtyzwb ปีที่แล้ว +2

      @@m0923678421 我说的是CPU到底是如何工作的,如果你从电子线路学明白了CPU的工作原理,指针只不过是很简单的事情

    • @m0923678421
      @m0923678421 ปีที่แล้ว +2

      @@czwbtyzwb 你可能是天選之人,我偏努力型,雖然現在看起來很簡單,對於那時候的我(自動控制大二下)來說,不理解就是不理解,那時候連C語言為什麼可以這樣 I = I+1;也不知道,LED為何要加限流電阻,電阻怎麼計算這種簡單的,我那時也都不懂,是從我開始玩改裝機車LED,DIY燈板時才上網找資料,看到其他人分享介紹後才知道怎麼計算,也有可能我應該去讀技職學校,讀錯了(笑淚),不過到了大三大四再回頭來看就瞬間明白,挺奇妙的,被當掉後重修滿分,如果教授們可以不要這麼古板,也許學生們可以再更早一點明白且理解,就不用浪費這麼多時間

    • @LF58888
      @LF58888 ปีที่แล้ว

      ​@@czwbtyzwb确实,但是这个我没记错的话大学这个是选修

  • @Alan_Skywalker
    @Alan_Skywalker ปีที่แล้ว +6

    在冯诺依曼架构里,内存条仍然是内存,外存指的是硬盘这些。缓存也就是字面意义上的,把内存中常用或指定的数据和指令提前加载或保存,以加快访问速度降低延迟。
    其实存储器的速度和存储器在CPU架构中的位置关系更大一些。比如同样是SRAM,L1可以比L3快上十几倍,而同样是DRAM,在4代至强中集成的HBM速度也可以达到700GB/s。

  • @6051徐翊喬
    @6051徐翊喬 ปีที่แล้ว +1

    這頻道真到讓我對半導體產生興趣,超讚

  • @早餐-l9t
    @早餐-l9t ปีที่แล้ว +8

    CPU的缓存是用来优化指令执行与重排的,不是必要构件,而内存就是体系中必要的构件

    • @robertnull6653
      @robertnull6653 11 หลายเดือนก่อน

      少了緩存要如何設計具有當代效能的CPU?

    • @atussentinel
      @atussentinel 11 หลายเดือนก่อน +1

      @@robertnull6653 你们两个说的必要性完全不是一个东西😅

  • @ohyt1004
    @ohyt1004 ปีที่แล้ว +9

    意思差不多到位了. 在CPU中再將 Virtual Memory Address 轉一手才到 Physical Memory; 寄存器不可以用 & 取址, 他的位址藏在彙編碼中, 也就8個或16個而已

  • @DFA_Parser
    @DFA_Parser ปีที่แล้ว +3

    我想起来了我们这学期CS447学汇编语言,然后用Logism自己画CPU电路图实现汇编指令集,真的是很有用的一门课。

  • @simengfu7352
    @simengfu7352 ปีที่แล้ว +3

    基本上碰这个topic的话,都是要被指错误的。就像下面有朋友指出的,了解assembly的话,可能会更好理解pointer。我见过对pointer最好的诠释,就是"只可意会不可言传"😅

  • @Weichen-t5k
    @Weichen-t5k ปีที่แล้ว +4

    真的很讚喔,雖然知道指針的架構,但是對電路架構就不是那麼熟悉。

  • @stephensu4371
    @stephensu4371 ปีที่แล้ว +15

    指針是指向某個內存地址的數值,然後賦予給某個字符,學完assembly 語言就會容易理解,當時我的一個朋友學assembly的時候就哭了,還說這是什麼什麼鬼玩意,還要尋址,還要在16位地址加上4位偏移碼,還要記得存了什麼寄存器,完了你還要把地址搞好以後從對應內存的數據挖出來放進某個寄存器,最後再放回去,😂

    • @owoouo9167
      @owoouo9167 ปีที่แล้ว +1

      單從編程語言的層面理解還是太膚淺

    • @kevinlantw
      @kevinlantw ปีที่แล้ว +1

      沒錯, 當年我學的時候的確是先學了x86 Assembly才學C語言, 指針這種東西輕鬆秒殺(?). 當然如果能配合對CPU架構的理解會更全面, 不過單就以寫代碼混飯吃的角度, 其實也未必要研究到這個程度.

    • @stephensu4371
      @stephensu4371 ปีที่แล้ว +2

      @@kevinlantw 我是電子工程的,面向FPGA開發和telecom方面,必須要學這些東西

    • @robertnull6653
      @robertnull6653 11 หลายเดือนก่อน +1

      所以本科生出來就往後端,系統韌體方面走,別跟人搶前端開發了

  • @liang3163
    @liang3163 8 หลายเดือนก่อน +2

    char a;
    char *p = &a
    should be: char* p = &a
    因为 p 是一个译码器变量(即一个地址),而char*是前缀(指针的前缀表示),*p是在等式的左侧是无意义的(*p在右侧有意义,表示地址p上的储存的值)
    &a做的就是把a的译码器变量(即a所在的地址)拿出来。
    更底层的逻辑,要涉及到“间接取址 是如何通过 硬件电路 实现的”这个话题

  • @wizardy6267
    @wizardy6267 ปีที่แล้ว

    提高算法速度最基本的办法就是减少Cache miss,所以才有在不同条件下选择合适的据结构可以大幅度提升算法运算速度的说法。在C/C++里如果要改写linker script也是要对Memory Layout有概念的。指针及地址还有一个很有用的地方是在C++里,用来区分lvalue 和 Rvalue, 取不到地址就是Rvalue,其他的都是Lvalue~

  • @atussentinel
    @atussentinel 11 หลายเดือนก่อน +1

    对缓存的解释不错。但指针指向内存地址这个说法其实没错。缓存也是把内存的一部分映射过来的,具体当核心访问地址的时候是访问了缓存还是内存中间还隔了一个缓存寻址。不过缓存寻址对核心来说可以认为是透明的,也就是核心一直认为自己在访问内存。
    至于C语言的指针,如果链接上libc还有操作系统的特性在里面,直接看到的一定是一个虚拟地址。C语言毕竟是一个高级语言,看到的东西都是底层抽象出来的

  • @yuenyuli7778
    @yuenyuli7778 ปีที่แล้ว +1

    小姐姐終於回來了 聲音很好聽

  • @huazhu
    @huazhu ปีที่แล้ว

    虽然物理上变量是从高速缓存读取的,但缓存不是程序空间,它是一个后插入的临时空间,分析指针和地址可以无视缓存的存在,你用DEBUG或者反汇编都不会给出缓存的地址,缓存的快表就是对应实际的存储器地址,操作系统也不需要考虑cpu缓存对地址的影响。

  • @JackTAN61
    @JackTAN61 ปีที่แล้ว +7

    0:13 這裏說法出現誤區了!!
    L1快取記憶體是386以後的電腦才出現的!!
    而早在286時代,內存就與CPU相依為命!! 所以它的內存名稱是元配!! 別因為有小三就把元配冷落了!! 啥外存外存?? 說誰呢?? 你才外存!! XDDDD

    • @Mong-Yun_Chen_54088
      @Mong-Yun_Chen_54088 ปีที่แล้ว +2

      你才外存咧,你全家都外存。(咦

    • @JackTAN61
      @JackTAN61 ปีที่แล้ว +1

      @@Mong-Yun_Chen_54088 XDD

    • @robertnull6653
      @robertnull6653 11 หลายเดือนก่อน +1

      在古早時代比如IBM 360那時,那時記憶體肯定也沒有DRAM快速,所以整個架構的重點是要有記憶體儲存變量跟指令,而不是記憶體如何分級吧? 隨著處理器運算速度增加,自然會發展出更快讀寫的記憶體設計滿足溝通需求

    • @JackTAN61
      @JackTAN61 11 หลายเดือนก่อน

      @@robertnull6653 應該是說,剛開始擺個麵攤做生意,有塊砧板切滷菜就好了!
      生意做大後改成麵館,切個滷菜也要在流理台上處理!
      後來變成餐廳,就算一樣是切滷菜,為了搞排盤,不只是砧板,其他啥鬼東西都出現在案板上了!
      搞了一堆花俏的排盤一起上菜,但客人吃的還是滷菜!🤣🤣🤣

  • @imsailorjames
    @imsailorjames ปีที่แล้ว +2

    缓存那里有问题呐。内存条就是内存,缓存是加快CPU和内存之间的传输而加上去的。不少单片机上,缓存是可以关掉的。关掉之后,程序依然可以执行,只是执行效率变低了。

  • @zzxxccvv1810
    @zzxxccvv1810 ปีที่แล้ว +1

    你是第一个从硬件原理层面诠释指针的。

  • @joshuachan6317
    @joshuachan6317 ปีที่แล้ว +9

    愛上半導體 已經變成 愛上編程 了😂

    • @Lihouyi
      @Lihouyi ปีที่แล้ว

      比很多老师讲得好。

    • @Peter.Joe.39
      @Peter.Joe.39 ปีที่แล้ว +2

      @@Lihouyi 读音是ai合成的,想不到吧?🤣 ai取代老师,不久的将来

    • @idiode
      @idiode  3 หลายเดือนก่อน +1

      @@Peter.Joe.39 你错了 这是真人读音

  • @sydney2441
    @sydney2441 ปีที่แล้ว +7

    Stack 是存在內存裡的吧 只是要用的時候會被烤到cache 但ram裡的也不會刪掉

    • @tommymairo8964
      @tommymairo8964 ปีที่แล้ว +1

      call stack 那麼大,cache 存不下的……

    • @donnieyang7453
      @donnieyang7453 ปีที่แล้ว +1

      对,小姐姐的硬件功底很好,对软件的理解需要加强。

    • @kayanli91
      @kayanli91 2 หลายเดือนก่อน

      沒錯喔

  • @Lihouyi
    @Lihouyi ปีที่แล้ว +4

    这个老师啥都懂。厉害厉害。快比得上我了。讲得不错。

    • @dogcat5837
      @dogcat5837 ปีที่แล้ว +1

      徒儿,为师总是告戒你人外有人天外有天。做事不可张扬。

  • @davidjia5634
    @davidjia5634 ปีที่แล้ว +1

    电路上你可以这么理解。但是实际CPU运行的过程你还要稍微多深入一点点。

  • @kjyhh
    @kjyhh ปีที่แล้ว +2

    謝謝分享,以為是説c語言原來還是説電路🤣。

  • @parrykevin45
    @parrykevin45 ปีที่แล้ว +20

    小姐姐对C语言指针理解有误,C语言可以设置断点,然后反汇编就可以看到指针,一般是内存中的地址,不是寄存器。

    • @menkiguo7805
      @menkiguo7805 ปีที่แล้ว

      寄存器和缓存不一样

    • @HalleyChen2001
      @HalleyChen2001 ปีที่แล้ว

      这里说的就是内存里面的值,不过这里内存没有按照存储矩阵画出,而是按照逻辑顺序画的

  • @許廷瑋-x6x
    @許廷瑋-x6x ปีที่แล้ว +1

    謝謝老師

  • @司徒布魯
    @司徒布魯 ปีที่แล้ว

    雖然我還是聽不太懂,不過感謝妳的講解。可能我也太愚鈍,哈哈。

  • @yadongx
    @yadongx ปีที่แล้ว +1

    不同记忆体的速度固然差异巨大,但是更重要的差异是延时。

  • @捉i小吉
    @捉i小吉 ปีที่แล้ว +1

    能不能講講傳輸線是如何傳輸電磁波和阻抗匹配和史密斯圖的應用呢

  • @wnlny233
    @wnlny233 ปีที่แล้ว

    受益匪浅

  • @rfrf1077
    @rfrf1077 ปีที่แล้ว +1

    能转分享学习内容不?

  • @nan-3082
    @nan-3082 ปีที่แล้ว

    小姐姐太棒了!

  • @24330327
    @24330327 ปีที่แล้ว

    感謝,大重要了資訊了

  • @stephensu4371
    @stephensu4371 ปีที่แล้ว +1

    2:18 小姊姊,妳讓我們這幫緩存分分鐘上百MB的情何以堪

  • @im_someone
    @im_someone ปีที่แล้ว +2

    下次講雙向可控矽

    • @idiode
      @idiode  3 หลายเดือนก่อน

      可以

  • @guntop5126
    @guntop5126 ปีที่แล้ว +2

    蔷蔷不讲电影,改讲半导体了

  • @tiaportal
    @tiaportal ปีที่แล้ว

    学习,怎样可以联系老师

  • @hugoelec
    @hugoelec ปีที่แล้ว

    可以對硬體的直接控制權太高
    這算可以搞病毒碼的等級
    通常會被系統沙盒隔開吧

  • @f4568525153
    @f4568525153 ปีที่แล้ว

    簡單粗暴 讚

  • @jackyzou2376
    @jackyzou2376 ปีที่แล้ว +1

    char *p = &a 其实是把变量a所在的地址存储到他本身存储的地址,也就是把0xf存到地址为0xf的内存去。

    • @huazhu
      @huazhu ปีที่แล้ว +1

      不要误导,是吧a变量的地址存到p变量的地址里,形象地说就是把a的门牌放到p门牌的房间里。a 和p在编译器里就是两个程序空间内给分配的内存地址。

  • @raylin513
    @raylin513 ปีที่แล้ว

    SRAM的電路圖給錯了,給成flip-flop了

  • @tommymairo8964
    @tommymairo8964 ปีที่แล้ว

    雖然但是,cache 和 RAM 不共享地址空間……

  • @shuochen3598
    @shuochen3598 ปีที่แล้ว +1

    内存的“内”指的是冯诺依曼体系的“内”。有了CPU、内存就已经是一个完备的机器,可以自主运行,只是这时候还没有办法输入指令和数据、以及输出结果。但是请想一下,当一台计算机加载完了程序并开始运行之后,输入输出设备是必要的吗?CPU+内存完全可以让它持续运行。你可以拔掉计算机的硬盘、显示器、键盘,只要OS(或者其上运行的逻辑程序)允许,且程序本身没有进行输入输出操作,它完全可以继续运行下去。但是你可以拔掉内存吗?那必然会死机。
    CPU+内存,就是图灵机的一个完备实现,内存就是那个纸带,怎么可能是“外”的东西?
    至于缓存,只是一种工程优化,它甚至不应该出现在这个话题中。程序代码本身是不应该感知缓存的(至少用户态不感知,至于OS要处理页面异常那是另一码事)。用通常的话来说,缓存是“透明”或者“不可见”的。

    • @michaelzap8528
      @michaelzap8528 ปีที่แล้ว

      内存不是纸带。 纸带是存储,类似硬盘。内存是实实在在的电路。
      同意你说的,缓存只是一种优化,还是物理级别的优化,不应该出现在“指针”这个话题里边。
      指针,就硬件而言,说白了,其实就是寄存器sp 里边放的东西。寄存器sp里边存放的是当前运行指令的用到数据的地址。计算机只有输出地址到地址线,数据才能自动读取。所以指针可以理解为,当前指令,其实就是当前运行的方程(function) 的stack frame里边的地址。

    • @shuochen3598
      @shuochen3598 ปีที่แล้ว +2

      @@michaelzap8528 内存就是图灵机模型中的纸带

    • @shuochen3598
      @shuochen3598 ปีที่แล้ว

      @@michaelzap8528 指针跟寄存器也没有强绑定,寄存器BP只是x86架构的实现方案而已,在其他指令集中并不一定有一个固定的寄存器来表示指针,比如在riscv指令集允许用除了x0之外的31个寄存器中的任何一个来保存内存地址。指针是C/C++等高级语言中的抽象概念,在汇编及更低的层面并不存在指针这种西。

    • @michaelzap8528
      @michaelzap8528 ปีที่แล้ว

      ​@@shuochen3598 不是。纸带必须转化成电流,并且传到“内存”,也就是circuit才是内存。

    • @michaelzap8528
      @michaelzap8528 ปีที่แล้ว

      ​@@shuochen3598 指针就是地址。汇编或者高级语言的无论是变量地址或是指令地址,全部是由两个寄存器自动产生的,一个是SP,一个是IP。
      指针的物理意义就是SP和IP寄存器。

  • @吹推绿隐跳
    @吹推绿隐跳 ปีที่แล้ว

    请问,那地址p的值又放哪了。。。也要来个&p吗。。

    • @cheongboonleong1040
      @cheongboonleong1040 ปีที่แล้ว +1

      这就是指针的指针了

    • @吹推绿隐跳
      @吹推绿隐跳 ปีที่แล้ว

      @@cheongboonleong1040 难道可以无限套娃下去吗😅😅

    • @slipperstree
      @slipperstree ปีที่แล้ว +5

      @@吹推绿隐跳 地址p也是一个变量,当然也会为这个变量分配一个地址,而这个地址是固定的,编译器会在编译的时候将所有访问p的地方替换成实际的地址。所以不需要无限套娃。只要套娃到最后一层变量就变成固定地址了。因为编译器是知道每一个变量的地址的。所以会直接用地址替换p这个变量。up讲的是比汇编更低的物理层原理。不一定都能和c语言对应的上,但重点是物理层原理而不是编译原理。意思到了就够了。从物理层到c语言中间隔着很远。c语言已经是高级语言了。

    • @吹推绿隐跳
      @吹推绿隐跳 ปีที่แล้ว

      @@slipperstree 所以你的意思是,地址类型的P是固定地址,所以套娃结束了,那一般变量a的地址不是固定的吗?希望再多问你下哈哈O(∩_∩)O

    • @slipperstree
      @slipperstree ปีที่แล้ว +6

      @@吹推绿隐跳 变量a的地址也是固定的。举个例子,char a=1; char* p=&a; 这两句代码,变量a的地址为101号房间,里面存着数字1,变量p是指向变量a的指针,p的地址是房间102,里面存着数字101,当程序直接访问变量a的时候,就直接访问101房间并取出数字1,而当程序通过p访问a的时候,编译器会先从102号房间里取出101再去101房间取出数字1。

  • @meow4619
    @meow4619 ปีที่แล้ว

    细节可以参考 计算机组成原理 这本书

  • @biggary6427
    @biggary6427 ปีที่แล้ว

    38譯碼器真直觀

  • @黃先生-d7o
    @黃先生-d7o ปีที่แล้ว

    Good~

  • @tiaportal
    @tiaportal ปีที่แล้ว

    C#没有指针,有没有办法解决

    • @atussentinel
      @atussentinel 11 หลายเดือนก่อน

      引用的实现就是指针啊,C#有ref,out还有this
      C++传送的引用也是指针,主要是像C那样裸指针太危险
      当然c#出的是IL,和真正跑在CPU上的指令还差了一层

  • @user-saint
    @user-saint ปีที่แล้ว +1

  • @徐丽
    @徐丽 4 หลายเดือนก่อน +1

    从b站上过来的

  • @tianya6666
    @tianya6666 ปีที่แล้ว

    妹子研究得够深入呀

  • @kevinlantw
    @kevinlantw ปีที่แล้ว

    好久沒寫C/C++了...真讓人懷念.
    以前剛從事程式工作的時候有一個跨平台(porting)的專案, 印象中用到了前置五個*的變數 , 不過那也是沒辦法, 原本的平台是ROM寫死的, 也沒有file system. 後來想了很多辦法去處理, 現在回想, 那時候沒經驗但真的是腦力的高峰期...

  • @donnieyang7453
    @donnieyang7453 ปีที่แล้ว

    对指针的表达不准确,指针p,和变量a本质都是数据,都存储在右边的内存里,分别有自己的地址,可供访问。数据被读取出来后(如0x80008000),再照声明类型去解释,如int *p, 那么CPU就认为它是个地址,如是int a,那么就是值.

    • @atussentinel
      @atussentinel 11 หลายเดือนก่อน

      前面是对的后面不准确。类型是给编译器看的,编译之后类型的不同就消失了,CPU看到的只有地址和地址里的值。

  • @Lihouyi
    @Lihouyi ปีที่แล้ว

    就不知道 老师是男的还是女的。 纳电池可以帮忙讲解一些么?

    • @idiode
      @idiode  3 หลายเดือนก่อน

      男的

  • @michaelzap8528
    @michaelzap8528 ปีที่แล้ว

    小姐姐你对指针的理解和解释是错的。
    缓存只是从内存读取数据的一种优化,还是硬件级别的优化,不应该出现在“指针”这个话题里边。
    指针,就硬件而言,说白了,其实就是寄存器BP 里边放的东西。寄存器BP 里边存放的是当前运行指令用到所有数据的地址的起始地址。计算机只有输出地址到地址线,数据才能自动读取。所以指针可以理解为,当前指令,其实就是当前运行的方程(function) 的stack frame里边的地址。每一个function里边的变量,无论是parameter ,还是local variable, 翻译成汇编语言(机器语言)后,其实都变成了BP+X(parameters) , 和BP-X (local variable).
    寄存器BP+/-X 就是指针,因为它里边装的是变量的地址。
    每个BP+/- X 指向的stack frame 里边,还可以再放当前function 的任何BP+/- X, 这个就是c/c++ 软件意义上的指针,也是它的真实的硬件含义。

    • @atussentinel
      @atussentinel 11 หลายเดือนก่อน

      这里指的应该不只是BP里的东西
      毕竟像x86还有 mov ax, [buffer] 这种寻址方式
      这里的buffer不是指BP+offset
      不应该出现缓存我是同意的。毕竟缓存寻址对核心来说基本是透明的

    • @michaelzap8528
      @michaelzap8528 11 หลายเดือนก่อน

      @@atussentinel 计算机任何变量,任何东西,都必须经过B P,或者IP(指令)才能取得“地址”。因为绝对的物理地址是不允许的。数据变量,都必须经过BP。BP的绝对物理地址是由操作系统,随机赋予的。
      [buffer]中的buffer既然是变量,它也必须由BP赋予地址。严格地说,是由stack frame赋予的。

  • @ziyunzhuimeng4594
    @ziyunzhuimeng4594 ปีที่แล้ว

    槽点好多。实际上,某个变量到底在内存还是寄存器里,是编译器决定的,用户可以通过编译选项以及关键字影响它。还有就是实模式与保护模式的区别。至于内存为啥慢,一大原因是被总线卡脖子……叫外存还是算了,内存叫外存,那磁盘叫啥?不过这个视频的重点似乎不是c语言而是ram和译码器就是了……

  • @fei4295
    @fei4295 ปีที่แล้ว +2

    固态硬盘4G/说得言过其实了,能达到500MB/s都谢天谢地了😅

    • @wat9254
      @wat9254 ปีที่แล้ว

      pcie4的ssd可以8g了

    • @j8888x
      @j8888x ปีที่แล้ว

      4Gbit/s=500mb/s 8bit=1Byte

    • @fei4295
      @fei4295 ปีที่แล้ว

      @@j8888x 原来是这样啊,差点蒙在鼓里了😅😅