【原创】浅谈指针(六)字符串相关

本文原创,仅发布于博客园,如在其他网站看见均为盗取

今天学校有计算机拓展课,抽出时间来写一篇关于指针的文章。
指针我之前已经写过五篇文章了,这一篇还是一样,来讲指针。指针是C++中非常值得研究的知识点。因此,想要把指针学好,是不容易的。

前言

今天学校里面看见有人问我一个问题,说是字符串比较的问题。

char s[10];
...
if(s=="123456789")...

没有语法错误,但是运行结果不太对。
大家可以在这个地方停一停,想想是为什么。

字符串比较strcmp

我们之前的文章应该讲过,如果没讲过或是不记得了,我们就再重新说一遍。

指针的比较

请在这里允许我摘录《征服C指针》的一段话:

1.1.8 C是只能使用标量的语言
对于标量(scalar)这个词,大家可能有些陌生。
简单地说,标量就是指 char、int、double 和枚举型等数值类型,以及指针。相对地,像数组、结构体和共用体这样的将多个标量进行组合的类型,我们称之为聚合类型(aggregate)。
早期的 C 语言一度只能使用标量。
经常听到初学者有以下的提问:
if (str == "abc")
这样的代码为什么不能执行预期的动作呢?确实已经将“abc”放到了 str 中,条件表达式的值却不为真。这是为什么?
对于这样的疑问,通常给出的答案是“这个表达式不是在比较字符串的内容,它只是在比较指针”,其实还可以给出另外一个答案:
字符串其实就是 char 类型的数组,也就是说它不是标量,当然在 C 里面不能用==进行比较了。

上面的解释应该是比较完善的。
在表达式中,数组如果后面不带[],就会在表达式中解释做指针。因此,在这里,数组名str会被解释做str的地址。
而我们的字符串常量,例如"abc",在表达式中也会解释做指针。实质上,这个东西本质是数组,我们来做一个简短的实验:

#include<bits/stdc++.h>
using namespace std;
char str[3];
int main(){
  printf("%p\n",str);
  printf("%p\n","abc");
  printf("%d\n",sizeof("abc"));
}

根据sizeof的结果,我们可以发现字符串常量的本质是数组而不是指针。(详细请见之前的文章,数组和指针的sizeof结果是不同的)
而str和"abc"的地址是截然不同的,因此,比较的结果一定不会相等。

strcmp

很多字符串处理的函数都包含在<string.h>中。
strcmp用于比较字符串的大小,返回值如下:

strcmp(a,b)
a=b 返回0
a<b 返回负数
a>b 返回正数

对于部分处理环境,a<b返回-1,a>b返回1,但是如果仅仅对1和-1判断,在部分环境还是过不去的。
strcmp的本质还是指针运算。我们举个例子,代码来源网上:

int strcmp(const char *src,const char *dst){
    int ret=0;
    while(!(ret = *src - *dst) && *dst)
        ++src,++dst;
    return ret;
}

代码其实比较复杂。由于用到了指针运算。指针运算其实比较复杂和灵活,我们解释while语句的指针运算。
src-dst表示比较结果,如果比较字符不相等,就会直接退出语句。而*dst表示比较的字符是否为'\0'。

strcpy

由于数组是不可变的,因此,执行str="abc"一类的语句是不对的。
我们需要使用strcpy来实现。

posted @ 2021-11-12 16:25  计算机知识杂谈  阅读(130)  评论(7编辑  收藏  举报