首页 > 编程语言 >C语言习题--程序改错

C语言习题--程序改错

时间:2024-09-05 20:50:36浏览次数:7  
标签:char src -- len 改错 dest 空字符 习题 sizeof

 1.待修改代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
   	char* src = "hello, world";
   	char* dest = NULL;                                   
	int len = strlen(src);
	dest = (char*) malloc(len);
	char* d = dest;
	char * s = src[len];
	while(len-- != 0)
		d++ = s--;
	printf("%s", dest);
    return 0;
}

        分析可知,此程序想要完成一次字初步符串反转的操作。

2.程序解析

1.char* src = "hello, world";

        定义了一个指向字符的指针src,并将一个字符串常量或叫字符串字面值的地址赋给src;

字符串常量所在的内存位置:由于常量存储于系统中的常量区,这部分的内存是不允许被修改的,不可以通过src修改它指向内存的内容;

字符串常量的长度:字符串常量除了包含双引号内的所有字符(包括空字符)以外的字符之外,还包括一个空字符 ‘\0’。如果执行printf(%s, src),程序会答应从src开始的每一个字符,知道遇到空字符;

另一种定义方式:char src[ ] = "hello, world";这种定义方式定义了一个字符串数组,同样是使用字符串常量进行初始化,但是系统会分配一段新的内存,并将字符串常量中的字符复制到内存中;这样使用*src 可以修改;

2.char* dest = NULL;

        定义了一个指向字符的指针src,并将其初始化为NULL;

3.int len = strlen(src);

        定义了一个整型变量,并且使用strlen库函数统计src中的字符个数,其中不包括空字符;

strlen:从当前指针指向的位置开始统计字符串的个数,直到遇上空字符;

4.dest = (char*) malloc(len);

        利用库函数malloc在系统的动态存储区或者说堆(heap)中开辟了一段存储空间,并将这一段存储空间的起始地址赋给 dest;

malloc:C语言中的库函数,用于动态内存分配。函数原型为 void * malloc(size_t size);

(1)此函数返回一个通用指针(void*)。这意味着在调用时必须进行类型转换,从而返回的指针成为预想的正确类型;
(2)size_t 是由系统通过 typedef 定义出来的一个新的类型,表示内存大小的基本单位,一般而言 1 size_t = sizeof(char);

sizeof:C语言中的运算符,操作对象可以是变量,也可以是数据类型,如果为数据类型,则应该用括号将其括起,如 sizeof(char);作用是:计算操作对象所占的内存空间;注意,该操作是在编译阶段完成的;int a; double b; sizeof(a = b) 得到的内存大小与 sizeof(a)相同;

此处使用  dest = (char*) malloc(len * sizeof(char)); 会更加规范;

5.char* d = dest;

        定义一个指向字符的指针 d,并将 4 中申请的内存首地址赋值给 d;

6.char * s =  src[len];

        定义一个指向字符类型的指针 s,并且选择src指向的内存,并将其偏移 sizeof(char) * len 的长度,然后取出其中的内容,赋值给s

错误:此处出现了一个错误,将字符赋给一个字符指针将导致不可预见的结果;

修改:此处应该将其改为 char* s = &  src[len - 1]  或者 char* s = src + sizeof(char) * (len - 1);

为什么是 len - 1? 由于 src数组包含一个空字符,&src[len] 会取到第 len + 1个元素的地址,也就是空字符的地址;

7.while(len-- != 0)
        d++ = s--;

        这个代码块对 d 向前遍历 len 次,对 s 向后遍历 len 次,然后将 s 的值赋给d;

错误:由于我们希望把src指向的字符串反转,我们应该将其指向的内容赋给 d 指向的内存中,而不是进行指针变量本身的赋值;

修改:此处应该对 d 和 s 都加上取地址符,*d++ = *s--;

8.printf("%s", dest);

错误:由于dest指向的字符串到最后没有空字符 ‘\0’,printf函数将一直沿着dest指向内存开始打印,直到遇到空字符,这样程序会出现不可预见的错误;

修改:在字符串末尾加上空字符。 dest[len] =  '\0';

3.修改后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
   	char* src = "hello, world";
   	char* dest = NULL;                                   
	int len = strlen(src);
	dest = (char*) malloc(len * sizeof(char)); //可以不修改
	char* d = dest;
	char * s = &src[len*= - 1];                //修改后
	while(len-- != 0)
		*d++ = *s--;                           //修改后
    dest[len] = '\0';                          //添加
	printf("%s", dest);
    return 0;
}

标签:char,src,--,len,改错,dest,空字符,习题,sizeof
From: https://blog.csdn.net/m0_65484315/article/details/141902455

相关文章

  • LINUX—网络编程——基础知识
    1、OSI开放模型        OSI模型相关的协议已经很少使用,但其本身却非常通用,它是一个理想化的模型,尚未有完整的实现。该模型共有七层结构,由低到高分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。每层的主要功能如下:          ......
  • 深入浅出:理解Python中的上下文管理器
    在Python编程中,上下文管理器是一个强大的工具,它允许我们更优雅地处理那些需要设置和清理的资源。本文将从概念入手,逐步深入到实现层面,帮助读者更好地理解和使用Python中的上下文管理器。什么是上下文管理器?上下文管理器是通过__enter__()和__exit__()方法来实现的类或......
  • C++基础知识
    1、基本概念1.1 引用类型(reference)        对一个数据可以使用"引用"(reference)类型,这是C++对C的一个重要扩充,引用是一种新的变量类型,它的作用是为一个变量起一个别名inta;int&b=a;        在声明变量b时变量a的引用后,在它......
  • 动手学习深度学习
    动手学习深度学习特点:数学原理推理+代码实现CH1引言引言:学习到一种数学的直觉​​机器学习路线:​​常见结构:​​‍为什么要有机器学习:机器学习是为了让机器学习到人类学不到的知识,人类学习的能力是有限的,只能通过简单的几种形式如语言,视频等来进行学习,但机器远不止于......
  • 章10——面向对象编程(高级部分)——抽象类
    介绍更多意义在于其设计意义。供子类参考的一个模板。注意细节final、private、static与重写矛盾,不可与abstract共用!补充说明static方法可以被继承,不可以被重写,若父子方法名相同,则会隐藏derive类派生类方法,调用base类基类方法。静态方法时编译时绑定的,而方法重写是运行时......
  • 语义分块:改进 AI 信息检索
    RAG系统及其挑战检索增强生成的流行是有充分理由的。它允许AI系统通过结合信息检索和语言生成来回答问题。标准的RAG管道通过摄取数据、检索相关信息并使用它来生成响应来实现这一点。然而,随着数据变得越来越复杂,查询也越来越复杂,传统的RAG系统可能会面临限制。这就是语......
  • 第十二讲 为什么表数据删掉一半,表文件大小不变?
    第十二讲:为什么表数据删掉一半,表文件大小不变?简概:问题:表删掉了一半的数据,表文件的大小还是没变?​ 经常会有同学来问我,我的数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变?InnoDB的表回收​ 那么今天,我就和你聊聊数据库表的空间回收,看看如何......
  • 报错时,考虑“版本命名一致性”
    安装paddleocr时报错:--------------------------------------C++Traceback(mostrecentcalllast):--------------------------------------0paddle_infer::Predictor::Predictor(paddle::AnalysisConfigconst&)1std::unique_ptr<paddle::PaddlePredictor,......
  • Win10bat自动校正系统时间
    本文介绍了如何处理Windows时间服务(w32time)在同步时遇到的两个问题:一是访问拒绝和服务未启动,需要在服务管理中设置启动类型;二是时间数据不可用,可通过修改注册表MaxPosPhaseCorrection和MaxNegPhaseCorrection的值来解决。 使用以下Bat命令进行自动脚本@echooffnetstopw......
  • CF704B Ant Man 题解
    题目传送门前置知识预设性DP解法考虑统计每个数单独的贡献,然后进行预设性DP。设\(f_{i,j}\)表示当前填了\([1,i]\)时有\(j\)个连续段的最小权值,边界为\(f_{0,0}=0\)。对\(i(i\nes,i\nee)\)填入的位置进行分讨。新开一段后面填入的数都比\(i\)大(如果存......