转行还挺难的,一喜一悲,起起落落的。蛮有趣,呵呵。人生是自己的,自己知道自己干什么就好了。
最近面试啊,学习啊的。其实看了很多博客。好多都是很多年前的,写的确实不错,感觉水平比我高。可是,不知道那些人还有坚持下去没有。程序员群体,不乏激情澎湃之时,想当年我也是热血沸腾的写着技术博客。只是岁月流逝,激情难耐寂寞啊。也许好多人都没能走下去,或者被工程的细节实际工作人际的纷繁所扰。忘了当初自己念念不忘的理想,对科学、哲学、艺术的某种很玄的追求。我辈如何强大,难挡时间侵袭啊。我们不知道未来在哪里,也不必去追寻了。它会来的,无论好坏。
付出了这么多代价,我真的希望可以走的长久一些。不必激情澎湃,只是在流年的岁月下往前一点点的走走,走走就好。
char* p = “abc”和char p[] = “abc”的区别
这也是面试题,只是出的方式没这么直接,当时我不会。现在略懂,写出来。
以前也大致知道内存区域划分为全局数据区、栈、堆、代码区。只是不知道还有一个文字常量区。“abc”这种就是在常量区的。
全局数据区,存储着全局变量、静态变量(全局或者局部)。
栈区,由编译器自动分配释放的,存放临时变量或者指针、数组、函数返回地址、传递参数等等。
堆区,由程序员动态申请、释放。
文字常量区,顾名思义了,就是存储文字量的,既然是常量,当然就不能修改,这也引出了题目中的区别,通过指针解引用修改时,会发生运行时错误,程序崩溃。
下面引用一段代码,据别人说是一位前辈写的,就是讲解下大致什么样的数据存储在什么区域。
//main.cpp
int a=0; //全局初始化区
char *p1; //全局未初始化区
main()
{
int b; //栈
char s[]="abc"; //s在栈上,运行时赋值。
char *p2; //栈
char *p3="123456"; //123456\0在常量区,p3在栈上。
static int c=0; //全局(静态)初始化区
p1 = (char*)malloc(10);
p2 = (char*)malloc(20); //分配得来得10和20字节的区域就在堆区。
strcpy(p1,"123456"); //123456\0放在常量区,编译器可能会将它与p3所向"123456"优化成一个地方。
}
上边的代码最后的strcpy会将文字常量拷贝到p1指向的堆上,修改时不会出问题。修改常量区的数据才会出问题。
接着说下栈和堆。
栈的分配是向低地址扩展的。比如在主函数里声明两个int,第一个的地址会大于第二个地址。但是数据的存储上是采用低低高高的原则,即低位的数据存储在低地址的字节里。这也就是小端存储(X86嘛)。当然栈的空间一般不会太大,如果申请的太大或者递归层次太深,就会耗尽,这时会stack overflow。
而堆就比较不同,操作系统会维护一份空闲内存的链表,当申请时,遍历链表找到第一个空间大于所申请的堆节点,然后从空闲链表中删除,一般在这个内存空间的首地址处记录本次分配的大小,以便删除。链表记录的内存空间节点地址是从低到高的,所以程序员申请得到的地址是从低到高的。比如先后new char[10],前一个地址会小于后一个地址。
又往前走了一步。