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;
}