本篇博客是对MOOC:向函数传递和返回字符串的笔记整理。
在进入题目这几个函数的编写之前,首先要在字符指针的定义上注意一点:
如果定义的字符指针,那么指针可以修改,而字符串不能修改;如果定义的数组名,那么相反,数组名不能修改,而字符串不能修改。原因就是pStr是一个指向常量存储区中的字符串的指针变量,可以修改它的指向,但是不能修改常量存储区中的值;而数组名str的值是一个地址常量,不能修改,而字符串自然可以修改(不然数组的内容都不能变了)。
这里我们只用字符指针定义数组来实现。首先是容易理解的方法:
unsigned int MyStrlen( const char *pStr)//指针变量,指向字符变量
{
unsigned int len = 0;
for (; *pStr!='0'; pStr++) //到数组出现\0为止
{
len++;
}
return len;
}
const的作用:保护指针变量所指内容不被修改,防止下面的函数运行改变字符串内容。
进一步简化:
unsigned int MyStrlen(const char *pStr)
{
const char *start = pStr;//*start指向字符串中首字符
while (*pStr)//即*pStr指向的字符不为NULL
{
pStr++;
}
return pStr - start;
}
这里注意两点:一是第三行const作用是使前后变量类型一致,都为const char;
二是pStr++的含义。它是指指针移动一个为止,也就是说指针+1后,指向的是字符串中第二个字符的地址。
当然老师也代码不需要过分简洁,要在满足质量因素的条件下设法提高程序的效率。
void MyStrcpy(char *dstStr, char *srcStr)
{
while (*srcStr != '\0')
{
*dstStr = *srcStr/
srcStr++;
dstStr++;
}
*dstStr = '\0';
}
同样有更简洁的方法:
void MyStrcpy (char *dstStr, cotist char *srcStr)
{
while (*dstStr++ = *srcStr++)
{
;
}
}
简洁的原因就在第三行。第一点,i++是先执行语句,再加一,所以while判断后,指针位置都加一,实现了循环的效果;第二点,就是while后面的条件:
while循环的一般格式为:
while(expr)
{
;//body
}
其中用来判断循环条件的expr可以是任意表达式。当其是赋值语句的时候,含义为,先执行赋值语句,然后对左值进行判断。如果左值为0则expr为假,while退出;否则expr为真,while继续循环。
不过直接用赋值语句做expr时,编译器可能为认为赋值操作符=是等于判断符==的误写,这时编译器可能会报一个警告(warning),编译器是否报警,及报警告还是错误(error)取决于编译器设置。为避免这种情况,可以用while((var = expr))的形式,告知编译器就是要先赋值再判断,编译器就不会理会了。
同样,实际操作中不需可以追求过分简洁。
#include
#define N 80
char *MyStrcat(char *dest, char *source);
int main()
{
char *first[2N+1];
char *second[N];
char *result=NULL;
printf("Input the first string:");
gets(first);
printf("Input the second string:");
gets(second);
result = MyStrcat(first, second);
printf("The result is : %s\n", result);
return 0;
}
char *MyStrcat(char *dest, char *source)
{
char *pStr=dest;
while(*dest!=0)
{
*dest++;
}
while(*source!=0)
{
*dest=*source;
source++;
dest++;
}
*dest='\0';
return *pStr
}
注意:由于没有检查数组边界,数组first[]的长度要足够大;最后不要忘了让*dest变成NULL数组;MyStrcat函数中为了让返回值为连接后的函数,一开始要用*pStr记录下来。