关于c++传值的疑问

725137 2013-08-28 05:59:25
我一般这么写:


class Student
{
public:

int age;
char * name;
void set(int age, char* name)
{
this->age = age;
this->name = name;
}
};


搞不懂有些人为什么要这样写,有意思吗?

class Student
{
public:

int age;
char * name;
void set(int age, char* name)
{
this->age = age;
int len = strlen(name);
this->name = new char[len+1];
strcpy(this->name,name);
}
};

...全文
220 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
725137 2013-08-28
  • 打赏
  • 举报
回复

int main(int argc, char* argv[])
{
    char * n = "abcddefg";
 
    Student st ;
    st.set(18,n);
    (*n) = 'x';
	
    cout<<st.age<<st.name<<endl;
    cout<<&(st.name)<<endl;
    cout<<(*n) <<endl;
 
    return 0;
}
为什么如果是指针的话,通过指针去将第一个字符变成x,程序就会崩溃呢?
725137 2013-08-28
  • 打赏
  • 举报
回复
嗯。已经明白了。int是按值传递的。char*是默认的是传首地址。感谢
725137 2013-08-28
  • 打赏
  • 举报
回复
引用 3 楼 pengjialaosan 的回复:
个人认为:为安全起见还是第二种好点。 比如,如果第一种写法: char * myName = new char[20]; ...//给myName赋值 Student me; me.set(25, myName); //此时me.name是OK的,其与myName指向同一块内存 delete [] myName; //此时myName被释放,me.name因为指向同一块内存,此时成为传说中的野指针。
嗯。刚刚按这种方法测试了,如果是在外面动态分配的话,是会导致野指针。但是我还是不太明白,为什么只对char*这种有效。如果是new的int的话,为什么又不会导致野指针了呢?
大尾巴猫 2013-08-28
  • 打赏
  • 举报
回复
第一种不好,name依赖类外部的变量。如果几十个student,外面还要用一个数组来保存这些name的字符串。不合理。 第二种,name是保存了,但是set的实现有问题。 通常,student都应该有个 student(int age, char* name)的构造函数,还应该有相应的拷贝构造,所以很有可能name已经分配过内存了,set当中应该先delete this->name,然后再new和strcpy。 我个人认为,name应该设计成 char name[20]这样的静态数组,通常名字的长度有限,直接用字符数组更方便一些。这样不用new delete,效率更好。拷贝构造和赋值重载也不要写。
725137 2013-08-28
  • 打赏
  • 举报
回复
引用 1 楼 max_min_ 的回复:
上面的写法是把传进来的name地址赋值给成员的name 下面的写法是自己分配内存空间来保存name的值! 具体要写什么写法,看实际工作需求了
问题是我测试过后,

int main(int argc, char* argv[])
{
	char * n = "zou";

	Student st ;
	st.set(18,n);
	n = "quan";
	cout<<st.age<<st.name<<endl;
	cout<<&(st.name)<<endl;
	cout<<&(n)<<endl;

	return 0;
}
打印后的地址根本不是我传入的那个参数地址,这里是按值传递的,并不是按地址传的。
starytx 2013-08-28
  • 打赏
  • 举报
回复
你的疑问也就是为什么有的人要给字符指针开辟空间,因为照你的写法,只是将外部的那个字符指针地址保存了下来,如果外部的字符空间失效(比如释放了),那你保存的这个指针还有什么用呢,所以保险的做法就是自己开辟自己的空间然后复制外部的字符串值到自己的空间中。也看具体应用,有时候是需要你的写法的。
彭家老三 2013-08-28
  • 打赏
  • 举报
回复
个人认为:为安全起见还是第二种好点。 比如,如果第一种写法: char * myName = new char[20]; ...//给myName赋值 Student me; me.set(25, myName); //此时me.name是OK的,其与myName指向同一块内存 delete [] myName; //此时myName被释放,me.name因为指向同一块内存,此时成为传说中的野指针。
freelancer_ex 2013-08-28
  • 打赏
  • 举报
回复
第一种写法name的生命期由调用的人控制 第二Student负责分配、释放name
max_min_ 2013-08-28
  • 打赏
  • 举报
回复
上面的写法是把传进来的name地址赋值给成员的name 下面的写法是自己分配内存空间来保存name的值! 具体要写什么写法,看实际工作需求了
modyaj 2013-08-28
  • 打赏
  • 举报
回复
第一种 方便 第二种 安全
qq120848369 2013-08-28
  • 打赏
  • 举报
回复
holds or has, is a question.
gdlk159 2013-08-28
  • 打赏
  • 举报
回复
常量字符串..........你到底要干什么?
KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法。简单匹配算法的时间复杂度为O(m*n);KMP匹配算法。可以证明它的时间复杂度为O(m+n).。 一.简单匹配算法 先来看一个简单匹配算法的函数: int Index_BF ( char S [ ], char T [ ], int pos ) { /* 若串 S 中从第pos(S 的下标0≤pos S[0] != S[1],S[1] != S[2],所以S[1] != T[0],S[2] != T[0]. 还是从理论上间接比较了。 有人疑问又来了,你分析的是不是特殊轻况啊。 假设S不变,在S中搜索T=“abaabd”呢?答:这种情况,当比较到S[2]和T[2]时,发现不等,就去看next[2]的值,next[2]=-1,意思是S[2]已经和T[0] 间接比较过了,不相等,接下来去比较S[3]和T[0]吧。 假设S不变,在S中搜索T=“abbabd”呢?答:这种情况当比较到S[2]和T[2]时,发现不等,就去看next[2]的值,next[2]=0,意思是S[2]已经和T[2]比较过了,不相等,接下来去比较S[2]和T[0]吧。 假设S=”abaabcabdabba”在S中搜索T=“abaabd”呢?答:这种情况当比较到S[5]和T[5]时,发现不等,就去看next[5]的值,next[5]=2,意思是前面的比较过了,其中,S[5]的前面有两个字符和T的开始两个相等,接下来去比较S[5]和T[2]吧。 总之,有了串的next值,一切搞定。那么,怎么求串的模式函数值next[n]呢?(本文中next值、模式函数值、模式值是一个意思。) 三. 怎么求串的模式值next[n] 定义: (1)next[0]= -1 意义:任何串的第一个字符的模式值规定为-1。 (2)next[j]= -1 意义:模式串T中下标为j的字符,如果与首字符 相同,且j的前面的1—k个字符与开头的1—k 个字符不等(或者相等但T[k]==T[j])(1≤k0 但k #include int KMP(const char *Text,const char* Pattern) //const 表示函数内部不会改变这个参数的值。 { if( !Text||!Pattern|| Pattern[0]=='\0' || Text[0]=='\0' )// return -1;//空指针或空串,返回-1。 int len=0; const char * c=Pattern; while(*c++!='\0')//移动指针比移动下标快。 { ++len;//字符串长度。 } int *next=new int[len+1]; get_nextval(Pattern,next);//求Pattern的next函数值 int index=0,i=0,j=0; while(Text[i]!='\0' && Pattern[j]!='\0' ) { if(Text[i]== Pattern[j]) { ++i;// 继续比较后继字符 ++j; } else { index += j-next[j]; if(next[j]!=-1) j=next[j];// 模式串向右移动 else { j=0; ++i; } } }//while delete []next; if(Pattern[j]=='\0') return index;// 匹配成功 else return -1; } int main()//abCabCad { char* text="bababCabCadcaabcaababcbaaaabaaacababcaabc"; char*pattern="adCadCad"; //getNext(pattern,n); //get_nextval(pattern,n); cout<传值。*/ } }//while if ( T[j] == '\0' ) return (i-j); // 匹配成功 else return -1; } // my_KMP 六.后话--KMP的历史 [这段话是抄的] Cook于1970年证明的一个理论得到,任何一个可以使用被称为下推自动机的计算机抽象模型来解决的问题,也可以使用一个实际的计算机(更精确的说,使用一个随机存取机)在与问题规模对应的时间内解决。特别地,这个理论暗示存在着一个算法可以在大约m+n的时间内解决模式匹配问题,这里m和n分别是存储文本和模式串数组的最大索引。Knuth 和Pratt努力地重建了 Cook的证明,由此创建了这个模式匹配算法。大概是同一时间,Morris在考虑设计一个文本编辑器的实际问题的过程中创建了差不多是同样的算法。这里可以看到并不是所有的算法都是“灵光一现”中被发现的,而理论化的计算机科学确实在一些时候会应用到实际的应用中。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lin_bei/archive/2006/09/20/1252686.aspx

65,199

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧