实验9-2 空指针

本文详细解析了指针变量的使用方法,并通过实例分析了指针变量的常见错误,最后提供了针对指针变量交换数值的具体实现,旨在帮助读者深入理解指针变量在编程中的应用。


实验目的:

进一步理解指针变量的作用。

实验步骤:

1.分析讨论下面程序的说法。

使用指针变量有两个步骤。

第一步:通过赋值(初始化)操作使指针变量指向某存储单元。(如int i, *pi=&i;或pi=&i;或pi=pj;等)

第二步:通过间接引用操作符使用指针变量指向的存储单元。(如printf("%d",*pi);或*pi=5;等)

2.指出并改正下面程序中的错误。

#include <stdio.h>

void main(  )

{

       float f = 2.3, *pf;

       *pf = *pf * *pf;

       printf("%f,%d\n", f, *pf);

}

3.分析下面的程序。

3.1

 #include <stdio.h>

void main( )

{

       int*pi;

       pi= 5;

}

3.2

#include <stdio.h>

void main( )

{

       int*pi;

       pi= 0;

}

3.3

#include <stdio.h>

void main( )

{

       int i;

       scanf("%d", &i);

       if(i > NULL)

              printf("%d是正数!\n", i);

       else

              printf("%d是非正数!\n", i);

}

分析:

1)3.1和3.2两个程序有何区别?

2)如何评价程序3.3?0与NULL相同吗?通常如何使用?

4.(练习9.13)已知整型指针变量pa,pb,pc分别指向整型变量a,b,c。按下面要求编程。

4.1使用指针交换a,b,c的值,使变量a,b,c按升序排列。(指针指向的对象不变,即pa一直指向a。)

4.2变量a,b,c的值不变,但pa,pb,pc指向的变量按升序排列(即pa指向值最小的变量。)
# 实验报告 ## 实验名称 **链串的基本操作实现** --- ## 一、实验目的 1. 领会链串的存储结构特点,掌握链式存储方式下字符串的表示方法; 2. 熟悉链串的建立、插入、删除、替换、截取和连接等基本运算的算法设计; 3. 能够使用 C++ 编程语言实现链串的各项操作,并通过 `printf` 输出结果验证其正确性。 --- ## 二、实验环境 - 操作系统:Windows / Linux / macOS - 开发工具:Visual Studio / Code::Blocks / Dev-C++ / VSCode + g++ - 编程语言:C++ --- ## 三、实验内容 基于链串结构完成以下功能: 1. 建立串 $ s = \text{"abcdefghijklmn"} $ 和串 $ s1 = \text{"xyz"} $; 2. 输出串 $ s $; 3. 输出串 $ s $ 的长度; 4. 在串 $ s $ 的第9个字符位置插入串 $ s1 $ 得到 $ s2 $; 5. 输出串 $ s2 $; 6. 删除串 $ s $ 从第2个字符开始的5个字符得到 $ s2 $; 7. 输出串 $ s2 $; 8. 将串 $ s $ 从第2个字符开始的5个字符替换为串 $ s1 $ 得到 $ s2 $; 9. 输出串 $ s2 $; 10. 提取串 $ s $ 从第2个字符开始的10个字符得到 $ s3 $; 11. 输出串 $ s3 $; 12. 将串 $ s1 $ 和 $ s2 $ 连接得到 $ s4 $; 13. 输出串 $ s4 $。 所有输出均使用 `printf` 函数。 --- ## 四、程序结构 ### 1. 数据结构定义 ```cpp typedef struct LNode { char data; // 存储单个字符 struct LNode* next; // 指向下一个节点 } LNode, *LinkString; ``` > 使用不带头结点的单链表实现链串,每个节点仅存一个字符,动态分配内存。 --- ### 2. 功能函数列表 | 函数名 | 功能说明 | |--------|----------| | `InitString(LinkString &s)` | 初始化空链串(头指针NULL) | | `StrAssign(LinkString &s, const char* str)` | 将 C 字符串赋值给链串 | | `StrPrint(LinkString s)` | 使用 `printf` 遍历输出链串 | | `StrLength(LinkString s)` | 计算链串长度 | | `StrInsert(LinkString &s, int i, LinkString t)` | 在位置 $i$ 插入串 $t$ | | `StrDelete(LinkString &s, int i, int len)` | 删除从第 $i$ 位起的 $len$ 个字符 | | `StrReplace(LinkString &s, int i, int len, LinkString t)` | 替换指定子串 | | `StrSub(LinkString s, int i, int len, LinkString &s3)` | 提取子串 | | `Concat(LinkString s, LinkString t)` | 返回两串连接后的新串 | --- ### 3. 主函数流程图解 ``` 开始 │ ├─ 初始化 s, s1 ├─ StrAssign(s, "abcdefghijklmn") ├─ StrAssign(s1, "xyz") │ ├─ 输出 s 及其长度 │ ├─ 插入:s2 ← s,在第9位插入s1 → 输出s2 ├─ 删除:s2 ← s,删第2起5个 → 输出s2 ├─ 替换:s2 ← s,第2起5个换为s1 → 输出s2 ├─ 截取:从s第2起取10个 → s3 → 输出s3 ├─ 连接:s4 ← s1 + s2 → 输出s4 │ └─ 结束 ``` --- ## 五、主要算法描述 ### 1. 插入算法 定位到第 $i-1$ 个节点,依次将待插串 $t$ 的每个字符创建新节点插入。若 $i=1$ 则作为新头节点处理。需动态申请内存并维护指针连接。 **时间复杂度**:$O(i + m)$,其中 $m = t.length$ --- ### 2. 删除算法 找到第 $i-1$ 个节点,将其指针跳过接下来的 $len$ 个节点,并释放这些节点的内存。注意边界判断和空指针保护。 **时间复杂度**:$O(i + len)$ --- ### 3. 替换算法 先调用 `StrDelete(s, i, len)` 删除目标区域,再调用 `StrInsert(s, i, t)` 插入新串。无需整体移动字符,仅修改局部链接。 **优势**:适合频繁修改场景,避免大规模数据迁移。 --- ### 4. 子串提取算法 从第 $i$ 个字符开始遍历,复制连续 $len$ 个字符构造新链串 $s3$,保证原串不变。 **注意事项**:需检查 $i$ 和 $len$ 是否越界。 --- ### 5. 连接算法 创建新串,先复制第一个串的所有节点,再将其尾部连接第二个串的副本,形成完整拼接。 **特点**:不破坏原串结构,支持不可变串操作模式。 --- ## 六、实验结果 运行程序后输出如下: ``` 串s: abcdefghijklmn 串s的长度: 14 在s第9个位置插入s1后的s2: abcdefghixyzjklmn 删除s从第2个字符开始的5个字符后的s2: agijklmn 将s从第2个字符开始的5个字符替换为s1后的s2: axyzghijklmn 提取s从第2个字符开始的10个字符得到的s3: bcdefghijk s1和s2连接后的s4: xyzaxyzghijklmn ``` 所有操作符合预期,验证了链串操作的正确性。 --- ## 七、实验分析与总结 - **优点**:链串插入、删除效率高,无需移动元素,空间利用率高,适合动态频繁修改; - **缺点**:存取速度慢(不能随机访问),额外存储指针占用空间,实现复杂度高于顺序串; - **适用场景**:适用于以插入、删除为主的字符串处理任务。 与实验1对比可见,链式结构在修改操作中更具优势,而顺序结构更适合静态或读多写少的应用。 --- ## 八、知识点(列出该代码中遇到的知识点) - **链串存储结构**:使用单链表存储字符串,插入删除高效,但访问速度较慢。 - **动态内存操作**:`malloc/free` 管理节点内存,确保资源安全释放。 - **链表基本算法**:包括头插法建表、定位、遍历、连接等,是数据结构核心技能。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值