字符串拷贝函数

xiaoxiao2021-03-01  50

这次面试腾讯,面试官要我写个字符串拷贝函数,头一天晚上一晚上没睡好,脑袋昏昏沉沉的,之前看过C++中的字符串拷贝构造函数,先入为主,也没多想就开始了String类的拷贝构造函数,写完之后,将结果给面试官看,面试官说有几个问题,说怎么用这么长时间,然后我检查问题所在,第一个是字符串拷贝后,最后没有添加'\0',因为循环判断的条件是!='\0',所以很明显没有这个,将导致严重的安全问题,产生越界和内存非法访问问题。问题在于C语言中对字符串的读取是直到找到第一个'\0'才结束。虽然马上发现了,但是明显这是平时没有引起足够的重视引起的。第二个问题就是为什么要在里面重新开辟一块内存区来存储字符串,这个问题正是因为我把这个问题想成c++字符串拷贝构造函数,而C++的字符串实现中,字符串类大概定义如下:   class String   {   public:   String(const char *str = NULL); // 普通构造函数   String(const String &other); // 拷贝构造函数   ~ String(void); // 析构函数   String & operate =(const String &other); // 赋值函数   private:   char *m_data; // 用于保存字符串   };   而实现字符串拷贝构造函数基本就是如下:   String::String(const String &other)   {   int len = strlen(other.m_data);   m_data = new char[len+1];   strcpy(m_data, other.m_data);   }   晕哦,现在回想起来,当时整个脑子估计处于昏迷状态。   其实,就是简单的一个字符串拷贝,如果放在平时的话,简单的不能再简单。   char *strcpy(char *strDest, const char *strSrc);   {   assert((strDest!=NULL) && (strSrc !=NULL));   char *address = strDest;   while( (*strDest++ = * strSrc++) != '\0' ) NULL ;   return address ;   }   这里有三个需要注意的地方,第一个就是断言宏assert的使用,说真的,以前真还没具体的弄懂断言啥子个意思,assert这个单词用中文来理解真TM费力,倒是可以通过英语的解释来理解:   同义词: affirm declare insist on pronounce state   to declare or affirm solemnly and formally as true; affirm, verify   assert to be true; insist   这样来看,assert宏就是要求里面的条件都是真的,在运行过程中,如果assert 的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。   第二个:while( (*strDest++ = * strSrc++) != '\0' ) NULL ; 这里++运算符优先级较*高,而且这个里面隐式包含了将'\0'赋值给字符串最后,因为采用的 指针后++,当strSrc为最后一个字符时,条件为真,后++后,strSrc指向'\0',先赋值,再比较,条件为假,退出循环,不好理解,自己也可以采用好理解的方式写。如下:   while(*strSrc!='\0')   {   *strDest = * strSrc;   strDest++;   strSrc++;   }   *strDest ='\0';   第三个问题:strcpy 能把strSrc 的内容复制到strDest,为什么还要char * 类型的返回值?这是为了实现链式表达式。 所谓链式表达式就是可以将strcpy函数作为其他函数的参数。   例如 int length = strlen( strcpy( strDest, "hello world") );   这次技术面试的第一个问题就弄成这样,虽然后面的问题答的可以,但是显然这样的开始给面试官不好的映象,如果给人家第一映象都不好,也就难怪面试官也会在心理上先入为主啦,其实还有我在hr面的时候,hr对我的穿着形式也提出了建议,这个可能会决定我的这次面试成功与否,总之细小的地方注定成败,这句话我现在是有深刻的体会啦。
转载请注明原文地址: https://www.6miu.com/read-4150207.html

最新回复(0)