今天在写一个字符串字母大小写互转的一个函数的时候,修修改改终于完成了。代码如下:
#include "stdafx.h"
#include <string.h>
#include <iostream.h>
char *transform(char *cstr,char *str,int length);
int main(int argc, char* argv[])
{
char *str="woaini38";
cout<<str<<endl;
char s[10];
transform(s,str,strlen(str));
cout<<s<<endl;
return 0;
}
char *transform(char *cstr,char *str,int length)
{
for(int i=0;i<length+1;i++)
{
if (str[i]>='A'&&str[i]<='Z')
{
cstr[i]=str[i]+'a'-'A';
continue;
}
if (str[i]>='a'&&str[i]<='z')
{
cstr[i]=str[i]-'a'+'A';
}
else
{
cstr[i]=str[i];
}
}
return cstr;
}
哎!我承认我基础不是想象中的好。在写下这段代码的时候犯一个错误。
开始本来想把transform定义成(char *cstr,char *str)。然后在函数体中去为cstr业就是目标指针动态的分配内存,于是我写道:
char *transform(char *cstr,char *str)
{
int len=strlen(str);
cstr=new char [len];//动态分配一个len长度的内存
for(int i=0;i<len+1;i++)//下面的是一样的
{
if (str[i]>='A'&&str[i]<='Z')
{
cstr[i]=str[i]+'a'-'A';
continue;
}
if (str[i]>='a'&&str[i]<='z')
{
cstr[i]=str[i]-'a'+'A';
}
else
{
cstr[i]=str[i];
}
}
return cstr;
}
但是运行的时候包内存出错了,说某块内存不能读,或者某块内存不能写。编程这么久了,我立即就想到了这样的错误应该是用了空指针而导致的。我仔细检查但是没有找到,单步运行的时候知道是transform的cstr出了问题。但是我已经动态为他分配内存了啊!这个愁死我了。找不到原因,我试着用另一种写法,于是我动态分配的语句删除:但是循环的时候需要字符串长度变量。于是我传它一个length变量。然后在main函数我只能定义一个数组。然后给transform传参了。于是你就看到了开头的那段代码。
后来就一切顺利了。
但是我一直想不通为什么不能传递给transform一个空指针,然后在函数体中去动态分配内存呢?
在网上我看到这么一篇文章http://99381837.iteye.com/blog/905237
作者分析的挺不错了。他告诉我如果我要传递一个空指针的话,我就应该这么写char *transform(char **cstr,char *str){*cstr=(char *)malloc(strlen(str)+1);}
后面的分析看着就疼痛了。一下不能完全看下来。
其实写这篇文章也就是让自己不要再犯这样的一个错误。但是这个错误也让我想起了一个编程习惯。说尽量不要去使用空指针。但是我们在编程中却有时候不知道自己正在使用空指针。
于是我在VC中写下这么一段代码:
#include "stdafx.h"
#include <iostream.h>
#include <string.h>
int main(int argc, char* argv[])
{
char *str="woaini";
char *s;
strcmp(s,str);
cout<<s<<endl;
return 0;
}
这个时候我猜你应该知道怎么写这段代码了。
其实对于把一个空指针作为参数的这个做法还有一个错误被忽略了。你想如果你可以在函数体中去动态分配内存的话,那么你分配的这块内存什么时候可以得到释放呢?动态分配的内存是要手动释放的。这也是一个问题对吧。所以怎么写空指针都不应该作为参数传递的。
在大部分MFC的编程中,像字符串的传参都是CString的一个对象。有时候需要SDK的一些函数的时候,参数是指针的话,一定要记得分配内存,要不会出现错误。