现代程序设计——homework-08
写在前面
以下内容出自一个对C++只有一点点了解,几乎没有写过C++程序的人,理解上的一定会很不到位,请各位路过神牛多多指点。
博客内容为对
http://www.cnblogs.com/softwareTA/p/3419223.html
中相关问题的思考。
我的解答
1、生命周期
这个东西如果我能用十行代码演示,那我一定不是一个新手儿了,因为关于生命周期不同类型、不同版本的编译器是不一样的!
同一份代码:
#include <iostream> using namespace std; char* pointer_toStr() { char *s = "abcdefghijkl"; return s; } char* toStr() { char s[] = "abcdefghijkl"; return s; } int* toArray() { int s[4] ={1,2,3}; return s; } int main() { cout<<toStr()<<endl; cout<<pointer_toStr()<<endl; int* aaa; aaa=toArray(); cout<<aaa[0]<<endl; return 0; }
第一个问题:
cout<<toStr()<<endl的结果是什么?
为了回答这个问题而产生的一系列问题:
int* toArray() { int s[10] ={1,2,3,4,5,6,7,8,9,0}; return s; } int main() { int* array; array=toArray(); printf("%d\n",array[1]); printf("%d\n",array[1]); printf("%d\n",array[2]); int i; array=toArray(); for(i=0;i<10000;i++) ; printf("%d\n",array[1]); printf("%d\n",array[1]); printf("%d\n",array[0]); int arra[10]; array=toArray(); for(i=0;i<10;i++) arra[i]=array[i]; for(i=0;i<10;i++) printf("%d\n",arra[i]); }
这份代码的运行结果是什么?
对于问题1,看结果:
在Code::Blocks10.05+GNU GCC Compiler中,结果如下:
在VS 2012中
改了一个C语言版本的代码,结果如下:
PS:这个版本的函数调用顺序有一点点变化
对于引出的一系列问题:
看到这个结果,尼玛跟我开玩笑呢吧!
我的解释:
生命周期固然是函数调用返回之后就GameOver了,但是,这句话应该这么说,函数调用返回之后运行栈内的生命就GameOver了,堆中的内存,编译器是不能准确知道它的生命周期是什么时候结束的。在C++编程思想中有这么一段话:“注意,C 堆管理器相当重要,它给出内存块,对它们使用free( )时就回收它们。没有对堆进行合并的工具,如果能合并就可以提供更大的空闲块。如果程序多次分配和释放堆存储,最终会导致这个堆有大量的空闲块,但没有足够大且连续的空间能满足我们对内存分配的需要。但是,如果用堆合并器移动内存块,又会使得指针保存的不是相应的值”。
我们的结果也能证明这一点,函数返回了,堆中的生命还在苟延残喘,你还有几纳秒的时间来使用它们。当然这是有情可原的,堆操作本来就慢,再加上函数返回那么多事儿要处理,CPU哪有闲情管你呃。那么,什么时候堆上的东西正式死亡呢?函数返回之后并且这片空间被再次使用(对于编译分配的读写均可,对于malloc分配的,只有写)之后才正式死掉!
2、堆栈分配
这个话题好大有没有!同一个变量放在什么地方即使同一种、同一版本在不同机器上都可能不同!
int array[]={1,2,3,4,5,6,7,8,9,0};和int *array=(int *)malloc(sizeof(int)*n);但是释放的方式是不一样的,后者只要不free(),它就一直在。前者上面已经解释过了。
int* Malloc_Array(int n) { int *array=(int *)malloc(sizeof(int)*n); for(int i=0;i<10;i++) array[i]=i; return array; } int* Stack_Array() { int array[10]; for(int i=0;i<10;i++) array[i]=i; return array; } int _tmain(int argc, _TCHAR* argv[]) { int *m_Array=Malloc_Array(10); int *s_Array=Stack_Array(); for(int i=0;i<10;i++) printf("%d\n",m_Array[i]); for(int i=0;i<10;i++){ printf("%d\n",s_Array[i]); } free(m_Array); for(int i=0;i<10;i++) printf("%d\n",m_Array[i]); system("pause"); return 0; }
这个运行结果大家基本都能正确写出来的。
3、智能指针
此处略,我没做过太大的工程,这个东西太耗效率,我不喜欢。
4、分割URL
// LifePeriord.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> #include <memory> using namespace std; using std::cin; //int array[]={1,2,3,4,5,6,7,8,9,0}; int _tmain(int argc, _TCHAR* argv[]) { string url; //std::shared_ptr<string> p_url(std::string url); cin >> url; //p_url=&url; int i=0; for(i=0;url[i]!='\0';i++){ switch (url[i]) { case ':': if(url[i+1]=='/'&&url[i+2]=='/'){ i+=2; } putchar(','); break; case '/': case '.': putchar(','); break; default: putchar(url[i]); break; } } system("pause"); return 0; }
搞成这么简单完全可以吧!不惧任何一个能访问的URL测试!