2024-08-15 05:48:49 +02:00
|
|
|
|
import{_ as s,c as i,o as a,a6 as n}from"./chunks/framework.CZRoMP2i.js";const t="/c/assets/1.L8V3GBrc.png",l="/c/assets/2.CdvhiwcU.png",e="/c/assets/3.D74t3-Xt.png",d="/c/assets/4.DqDR6Thp.svg",p="/c/assets/5.BzSkS-4w.svg",h="/c/assets/6.BPY9ZGed.svg",C=JSON.parse('{"title":"第一章:颇具争议的指针","description":"","frontmatter":{},"headers":[],"relativePath":"notes/01_c-basic/06_xdx/index.md","filePath":"notes/01_c-basic/06_xdx/index.md","lastUpdated":1723516792000}'),k={name:"notes/01_c-basic/06_xdx/index.md"},r=n('<div class="important custom-block github-alert"><p class="custom-block-title">IMPORTANT</p><p></p><ul><li>① <code>指针</code>是 C 语言中<code>最重要</code>的概念之一,也是<code>最难以理解</code>的概念之一。</li><li>② <code>指针</code>是 C 语言的<code>精髓</code>,要想掌握 C 语言就需要深入地了解指针。</li></ul></div><h1 id="第一章-颇具争议的指针" tabindex="-1">第一章:颇具争议的指针 <a class="header-anchor" href="#第一章-颇具争议的指针" aria-label="Permalink to "第一章:颇具争议的指针""></a></h1><h2 id="_1-1-概述" tabindex="-1">1.1 概述 <a class="header-anchor" href="#_1-1-概述" aria-label="Permalink to "1.1 概述""></a></h2><ul><li>目前而言,操作系统几乎都是通过 C 语言来编写和维护的;而 C 语言提供了指针的用法,其能直接操作内存地址,是个非常<code>强大</code>和<code>灵活</code>的工具;但是,需要开发者<code>小心谨慎的使用</code>,以确保程序的稳定性和安全性。</li></ul><div class="note custom-block github-alert"><p class="custom-block-title">NOTE</p><p></p><p>之所以指针在 C 语言中颇具争议,是因为一方面其功能强大,直接操作内存地址;另一方面,又很危险,不正确的使用指针的方式,非常容易导致程序崩溃。</p></div><ul><li><p>如果没有能很好的使用指针,就会带来一系列的问题,如:</p><ul><li>① <code>空指针引用</code>(Null Pointer Dereference):当一个指针没有正确初始化或者被赋予了空(NULL)值时,如果程序尝试访问该指针所指向的内存,会导致运行时错误,甚至导致程序崩溃。</li><li>② <code>野指针</code>(Dangling Pointers):指针指向的内存地址曾经分配给某个变量或对象,但后来该变量或对象被释放或者移动,导致指针仍指向已经无效的内存位置。对野指针进行操作可能会导致未定义的行为或程序崩溃。</li><li>③ <code>指针算术错误</code>:在进行指针运算时,如果没有正确管理指针的偏移量或者超出了数组的边界,可能会导致指针指向错误的内存位置,从而影响程序的正确性和安全性。</li><li>④ <code>内存泄漏</code>:如果动态分配的内存通过指针分配,但在不再需要时没有正确释放,会导致内存泄漏,长时间运行的程序可能会耗尽系统资源。</li></ul></li><li><p>为了减少指针带来的风险,开发人员可以采取以下的措施:</p><ul><li>① <code>良好的编程实践</code>:确保指针的初始化和使用是安全的,避免空指针引用和野指针问题。</li><li>② <code>边界检查</code>:在进行指针运算时,始终确保不会超出数组或内存分配的边界。</li><li>③ <code>使用指针和引用的适当性</code>:在可能的情况下,可以考虑使用更安全的语言特性,如:引用(在 C++ 等编程语言中)或者更高级别的数据结构来代替裸指针,从而减少指针使用时的潜在风险。</li></ul></li></ul><div class="important custom-block github-alert"><p class="custom-block-title">IMPORTANT</p><p></p><ul><li>① 既然指针很危险,那么通过一系列的手段将指针包装或屏蔽,以达到程序安全的目的(这是现代化的高级编程语言解决的思路,如:Java、Go、Rust 等)。</li><li>② 之所以,指针还需要学习,是因为在嵌入<EFBFBD>
|
2024-08-08 04:25:43 +02:00
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> main</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 定义变量,即:开辟一块内存空间,并将初始化值存储进去</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> num </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 访问变量,即:访问变量在内存中对应的数据</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"num = </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%d\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, num);</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 给变量赋值,即:给变量在内存中占据的内存空间存储数据</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> num </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 100</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 访问变量,即:访问变量在内存中对应的数据</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"num = </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%d\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, num);</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
2024-08-15 05:48:49 +02:00
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><ul><li>上述的这种方式也称为<code>直接访问</code>;当然,既然有<code>直接访问</code>的方式,必然有<code>间接访问</code>的方式,如:<code>指针</code>。</li></ul><div class="important custom-block github-alert"><p class="custom-block-title">IMPORTANT</p><p></p><ul><li>① 我们通过<code>变量名(普通变量)</code>访问内存中变量存储的数据,之所以称为<code>直接访问</code>的方式,是因为对于我们写程序而言,我们无需关心如何根据内存地址去获取内存中对应的数据,也无需关系如何根据内存地址将数据存储到对应的内存空间,这些操作步骤都是<code>编译器</code>帮助我们在底层自动完成的(自动化)。</li><li>② 但是,我们也可以通过<code>内存地址</code>去操作内存中对应的数据(手动化),这种方式就称为<code>间接访问</code>的方式了,相对于<code>直接访问</code>方式来说,要<code>理解</code>的<code>概念</code>和<code>操作</code>的<code>步骤</code>和之前<code>直接访问</code>的方式相比,要复杂和麻烦很多,但是效率高。</li></ul></div><h2 id="_3-2-内存地址和指针" tabindex="-1">3.2 内存地址和指针 <a class="header-anchor" href="#_3-2-内存地址和指针" aria-label="Permalink to "3.2 内存地址和指针""></a></h2><ul><li>其实,在之前《数组》中,我们就已经讲解了<code>内存地址</code>的概念了,即:操作系统为了更快的去管理内存中的数据,会将<code>内存条</code>按照<code>字节</code>划分为一个个的<code>单元格</code>,并为每个独立的小的<code>单元格</code>,分配<code>唯一的编号</code>,即:<code>内存地址</code>,如下所示:</li></ul><p><img src="`+d+`" alt="" loading="lazy"></p><div class="note custom-block github-alert"><p class="custom-block-title">NOTE</p><p></p><p>有了内存地址,就能加快数据的存取速度,可以类比生活中的<code>字典</code>,即:</p><ul><li>① 内存地址是计算机中用于标识内存中某个特定位置的数值。</li><li>② 每个内存单元都有一个唯一的地址,这些地址可以用于访问和操作存储在内存中的数据。</li></ul></div><ul><li>对于之前的代码,如下所示:</li></ul><div class="language-c vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> <stdio.h></span></span>
|
2024-08-08 04:25:43 +02:00
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> main</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 定义变量,即:开辟一块内存空间,并将初始化值存储进去</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> num </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
2024-08-15 05:48:49 +02:00
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><ul><li>虽然,之前我们在程序中都是通过<code>变量名(普通变量)</code>直接操作内存中的存储单元;但是,编译器底层还是会通过<code>内存地址</code>来找到所需要的存储单元,如下所示:</li></ul><p><img src="`+p+'" alt="" loading="lazy"></p><div class="note custom-block github-alert"><p class="custom-block-title">NOTE</p><p></p><p>通过<code>内存地址</code>找到所需要的<code>存储单元</code>,即:内存地址指向该存储单元。此时,就可以将<code>内存地址</code>形象化的描述为<code>指针👉</code>,那么:</p><ul><li>① <code>变量</code>:命名的内存空间,用于存放各种类型的数据。</li><li>② <code>变量名</code>:变量名是给内存空间取一个容易记忆的名字,方便我们编写程序。</li><li>③ <code>变量值</code>:变量所对应的内存中的存储单元中存放的数据值。</li><li>④ <code>变量的地址</code>:变量所对应的内存中的存储单元的内存地址(首地址),也可以称为<code>指针</code>。</li></ul><p>总结:内存地址 = 指针。</p></div><ul><li><code>普通变量</code>所对应的内存空间<code>存储</code>的是<code>普通的值</code>,如:整数、小数、字符等;<code>指针变量</code>所对应的内存空间<code>存储</code>的是另外一个变量的<code>地址(指针)</code>,如下所示:</li></ul><p><img src="'+h+`" alt="" loading="lazy"></p><div class="note custom-block github-alert"><p class="custom-block-title">NOTE</p><p></p><p>有的时候,为了方便阐述,我们会将<code>指针变量</code>称为<code>指针</code>。但是,需要记住的是:</p><ul><li>指针 = 内存地址。</li><li>指针变量 = 变量中保存的是另一个变量的地址。</li></ul><p>下文中提及的<code>指针</code>都是<code>指针变量</code>,不再阐述!!!</p></div><div class="important custom-block github-alert"><p class="custom-block-title">IMPORTANT</p><p></p><p>如果你观察仔细的话,你可能会发现<code>指针变量</code>和<code>普通变量</code>在内存中占据的存储空间是不一样的,那么到底是什么原因造成这样的结果?</p></div><h2 id="_3-3-指针变量的定义" tabindex="-1">3.3 指针变量的定义 <a class="header-anchor" href="#_3-3-指针变量的定义" aria-label="Permalink to "3.3 指针变量的定义""></a></h2><h2 id="_3-4-指针的作用" tabindex="-1">3.4 指针的作用 <a class="header-anchor" href="#_3-4-指针的作用" aria-label="Permalink to "3.4 指针的作用""></a></h2><ul><li>查询数据。</li><li>存储数据。</li><li>参数传递。</li><li>内存管理。</li></ul><p>在 Java 中,引用数据类型的向上类型转换(upcasting)和向下类型转换(downcasting)是面向对象编程中常见的操作。这些转换是 Java 继承体系和多态性的重要部分。我们先分别介绍向上类型转换和向下类型转换,然后讨论它们在 C 语言中指针的类似操作。</p><h3 id="向上类型转换-upcasting" tabindex="-1">向上类型转换(Upcasting) <a class="header-anchor" href="#向上类型转换-upcasting" aria-label="Permalink to "向上类型转换(Upcasting)""></a></h3><p>向上类型转换是将一个子类对象引用转换为父类对象引用。由于子类继承了父类的所有方法和属性,子类对象也包含父类对象的所有部分,因此这种转换是安全且隐式的。</p><p><strong><EFBFBD><EFBFBD>
|
2024-08-08 11:22:11 +02:00
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> makeSound</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Animal sound"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Dog</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> extends</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Animal</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> makeSound</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Bark"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Main</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> static</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> main</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">String</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[] </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">args</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Dog dog </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Dog</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Animal animal </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> dog; </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Upcasting, 隐式转换</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> animal.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">makeSound</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(); </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 输出:Bark</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><p>在这个例子中,<code>Dog</code> 类型的对象 <code>dog</code> 被转换为 <code>Animal</code> 类型。尽管 <code>animal</code> 引用的实际对象是 <code>Dog</code>,但在编译时,<code>animal</code> 被视为 <code>Animal</code> 类型。</p><h3 id="向下类型转换-downcasting" tabindex="-1">向下类型转换(Downcasting) <a class="header-anchor" href="#向下类型转换-downcasting" aria-label="Permalink to "向下类型转换(Downcasting)""></a></h3><p>向下类型转换是将一个父类对象引用转换为子类对象引用。由于父类对象不一定具有子类的所有方法和属性,因此这种转换需要显式进行,并且在运行时进行类型检查(使用 <code>instanceof</code> 关键字来确保安全)。</p><p><strong>例子:</strong></p><div class="language-java vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Main</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> static</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> main</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">String</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[] </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">args</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Animal animal </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Dog</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(); </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Upcasting</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (animal </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">instanceof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Dog) {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Dog dog </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Dog) animal; </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Downcasting, 显式转换</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> dog.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">makeSound</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(); </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 输出:Bark</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>在这个例子中,<code>animal</code> 引用的对象实际是 <code>Dog</code> 类型,在向下转换之前使用 <code>instanceof</code> 检查以确保安全。</p><h3 id="区别" tabindex="-1">区别 <a class="header-anchor" href="#区别" aria-label="Permalink to "区别""></a></h3><ul><li><strong>向上类型转换</strong>:隐式的,安全的,因为子类是父类的扩展。</li><li><strong>向下类型转换</strong>:显式的,可能不安全,需要运行时检查,因为父类不一定具有子类的特性。</li></ul><h3 id="c-语言中的指针转换" tabindex="-1">C 语言中的指针转换 <a class="header-anchor" href="#c-语言中的指针转换" aria-label="Permalink to "C 语言中的指针转换""></a></h3><p>在 C 语言中,指针的转换类似于引用类型的转换,但由于 C 语言没有继承和多态的概念,其转换更多是基于内存布局。</p><p><strong>例子:</strong></p><div class="language-c vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> <stdio.h></span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> printInt</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> ptr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%d\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)ptr);</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
2024-08-08 04:25:43 +02:00
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> main</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
|
2024-08-08 11:22:11 +02:00
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> voidPtr </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> &</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">x;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Upcasting, 隐式转换</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> printInt</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(voidPtr);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 输出:10</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> intPtr </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)voidPtr;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Downcasting, 显式转换</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%d\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">intPtr);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 输出:10</span></span>
|
2024-08-08 04:25:43 +02:00
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
2024-08-08 11:22:11 +02:00
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>在这个例子中,<code>void*</code> 是通用指针类型,可以指向任何类型的数据。将 <code>int*</code> 转换为 <code>void*</code> 是隐式的,而将 <code>void*</code> 转换为 <code>int*</code> 是显式的。由于 C 没有类型检查,因此这种转换需要程序员自己确保安全。</p><p>总结:</p><ul><li>Java 中的向上类型转换和向下类型转换是为了支持多态性和继承,向上转换是安全的,向下转换需要显式进行并且进行运行时检查。</li><li>C 语言中的指针转换没有多态性和继承的概念,但有类似的指针类型转换操作,程序员需要确保转换的安全性。</li></ul><h1 id="第四章-指针的运算-⭐" tabindex="-1">第四章:指针的运算(⭐) <a class="header-anchor" href="#第四章-指针的运算-⭐" aria-label="Permalink to "第四章:指针的运算(⭐)""></a></h1><h2 id="_4-1-概述" tabindex="-1">4.1 概述 <a class="header-anchor" href="#_4-1-概述" aria-label="Permalink to "4.1 概述""></a></h2><h2 id="_4-2-总结" tabindex="-1">4.2 总结 <a class="header-anchor" href="#_4-2-总结" aria-label="Permalink to "4.2 总结""></a></h2><ul><li><p>在 C 语言中,<code>普通变量</code>是直接存储<code>数据</code>的<code>变量</code>。对于普通变量,支持的操作包括:</p><ul><li>① <strong>赋值操作</strong>:给变量赋值,如:<code>int a = 5</code>。</li><li>② <strong>算术运算</strong>:可以对数值类型的普通变量进行加、减、乘、除等运算,如:<code>a + b</code>、<code>a - b</code>、<code>a * b</code>、<code>a / b</code></li><li>③ <strong>关系运算</strong>:可以进行比较运算(大于、小于、等于等),如: <code>a > b</code>、<code>a == b</code>。</li><li>④ <strong>逻辑运算</strong>:对布尔类型的值进行与、或、非运算,如: <code>a && b</code>、<code>a || b</code>、<code>!a</code>。</li><li>⑤ <strong>位运算</strong>:对整数类型的值进行位操作(与、或、异或、取反、左移、右移等),如: <code>a & b</code>、<code>a | b</code>、<code>a ^ b</code>、<code>~a</code>、<code>a << 2</code>、<code>a >> 2</code>。</li><li>⑥ <strong>自增自减运算</strong>:<code>a++</code>、<code>--a</code> 等。</li></ul></li><li><p>在 C 语言中,<code>指针变量</code>存储的是<code>另一个变量</code>的<code>地址</code>。对于指针变量,支持的操作包括:</p><ul><li>① <strong>赋值操作</strong>:可以将一个地址赋值给指针,如: <code>int *p = &a;</code>。</li><li>② <strong>解引用操作</strong>:通过指针访问它指向的变量,如: <code>*p = 10;</code> 修改指向变量的值。</li><li>③ <strong>指针运算</strong>: <ul><li><strong>指针和整数值的加减运算</strong>:指针可以进行整数的加减运算,用于访问数组或结构体成员,如: <code>p + 1</code>。</li><li><strong>指针的自增和自减运算</strong>:指的是内存地址的向前或向后移动,如:<code>p++</code>、<code>p--</code>。</li><li><strong>指针间的相减运算</strong>:两个指向同一数组的指针相减可以得到它们之间的元素个数,如
|
2024-08-08 04:25:43 +02:00
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ptr </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> arr;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 这句话是合法的,ptr现在指向arr[0]</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%p\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, arr);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 打印数组名,会打印数组首地址</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%p\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">arr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 打印第一个元素的地址</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div></li><li><p><strong>数组名是常量指针</strong>: 数组名是一个常量指针,不能改变它指向的位置,而指针变量可以改变它指向的位置。</p><div class="language-c vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> arr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">];</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ptr </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> arr;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 合法,ptr指向arr[0]</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ptr</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">++</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 合法,ptr现在指向arr[1]</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// arr++; // 非法,编译错误,因为数组名是常量,不能改变</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div></li><li><p><strong>sizeof运算符的结果不同</strong>: 使用<code>sizeof</code>运算符对数组名和指针变量会得到不同的结果,数组名会返回整个数组的大小,而指针变量会返回指针本身的大小。</p><div class="language-c vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> arr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">];</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ptr </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> arr;</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"sizeof(arr) = </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%lu\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">sizeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(arr));</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 返回数组的大小,5 * sizeof(int)</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"sizeof(ptr) = </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%lu\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">sizeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(ptr));</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 返回指针的大小,通常是4或8字节</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div></li><li><p><strong>地址运算符的结果不同</strong>: 使用地址运算符<code>&</code>对数组名和指针变量会得到不同的结果,对数组名使用<code>&</code>会返回数组的地址,而对指针变量使用<code>&</code>会返回指针变量本身的地址。</p><div class="language-c vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> arr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">];</span></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ptr </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> arr;</span></span>
|
|
|
|
|
<span class="line"></span>
|
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Address of array: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%p\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">arr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 返回整个数组的地址</span></span>
|
2024-08-13 04:40:27 +02:00
|
|
|
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Address of pointer: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%p\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">ptr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 返回指针变量ptr的地址</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div></li></ol><p>综上所述,通过这些示例和解释,可以看出数组名虽然在某些场合下可以像指针一样使用,但它并不是一个真正的指针变量,而是一个常量,表示数组的首地址。</p>`,87),c=[r];function o(g,E,u,b,y,F){return a(),i("div",null,c)}const A=s(k,[["render",o]]);export{C as __pageData,A as default};
|