C语言进阶知识点(持续跟新)
2011-08-18 11:20
169 查看
还是有点儿进阶的知识点,1.大段、小段内存模型
int val = 0x12345678; int *p1 = &val; char *p2 = (char *)p1; printf("%x\n",*p2); p2++; printf("%x\n",*p2); short *p3 = &val; printf("%x\n",*p3); p3 ++; printf("%x\n",*p3); return 0;运行结果:785656781234结论:(1)X86是小段(little endian),首先存储高位数值,然后依次向下存储。(与人类的思维不一样啊,反正记住,与读的顺序相反(读的意思是,我们从嘴巴读出来):先读的,后存储)(2)再次印证了指针类型的重要性(不只是指针类型,在这里我还要说一句,其实在计算机内存中并不存在所谓的数据类型,比如char,int等的。这个类型在代码中的作用就是让编译器知道每次应该从那个地址起始读取多少位的数据,赋值给相应的变量)2 结构体大小和位域结构体大小的计算http://www.cnblogs.com/leezhm/archive/2011/07/19/2110864.html(1)结构体大小计算: a、结构体中的第一个成员的首地址也即是结构体变量的首地址。 b、结构体中的每一个成员的首地址相对于结构体的首地址的偏移量(offset)是该成员数据类型大小的整数倍。 c、结构体的总大小是对齐模数(对齐模数等于#pragma pack(n)所指定的n与结构体中最大数据类型的成员大小的最小值)的整数倍。
struct { char a; int b; short c; char d; }dataAlign; struct { char a; char d; short c; int b; }dataAlign2;第一个结果大小是12,第二个是8;(2)位域的大小计算:满足上面结构体计算的三个法则,除此之外,还要满足: d、如果相邻位域类型相同,并且它俩位域宽度之和小于它的数据类型大小,则后面的字段紧邻前面的字段存储。 e、如果相邻位域类型相同,但是它俩位域宽度之和大于它的数据类型大小,则后面的字段将从新的存储单元开始,其偏移量为其类型的整数倍。 f、如果相邻位域类型不同,在VC中是不采取压缩方式,但是GCC会采取压缩方式。
struct { char a:4; int b:6; }bitChar2; struct { char a:3; char b:3; char c:7; double d; int e:4; int f:30; }bitChar;第一个大小为8,第二个大小为243.常量字符串位于静态存储区一道面试题引发的:
char* GetString1() { char p[] = "Hello World"; return p; } char* GetString2() { char *p = "Hello World"; return p; } int _tmain(int argc, _TCHAR* argv[]) { printf("GetString1 returns: %s. /n", GetString1()); printf("GetString2 returns: %s. /n", GetString2()); return 0; }答案:输出两行,第一行GetString1 returns: 后面跟的是一串随机的内容,而第二行GetString2 returns: Hello World.两个函数的区别在于GetString1中是一个数组,而GetString2中是一个指针。当运行到GetString1时,p是一个数组,会开辟一块内存,并拷贝"Hello World"初始化该数组。接着返回数组的首地址并退出该函数。由于p是GetString1内的一个局部变量,当运行到这个函数外面的时候,这个数组的内存会被释放掉。因此在_tmain函数里再去访问这个数组的内容时,结果是随机的。当运行到GetString2时,p是一个指针,它指向的是字符串常量区的一个常量字符串。该常量字符串是一个全局的,并不会因为退出函数GetString2而被释放掉。因此在_tmain中仍然根据GetString2返回的地址得到字符串"Hello World"。有关更多的内容见:1:http://hi.baidu.com/%D0%C7%BB%F0%D3%C4%C0%B6/blog/item/410174384e529ffbb211c71c.html:常量字符串为什么在静态存储区?2:http://blog.csdn.net/hackbuteer1/article/details/6706562:char str[]和char *str的区别4. (int&)a和(int)a的区别#include <iostream>#include <string>#include <cstdlib>using namespace std;int main(){float a = 1.0f;cout << (int)a << endl;cout << (int&)a << endl;cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?float b = 0.0f;cout << (int)b << endl;cout << (int&)b << endl;cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?}(int&)a == static_cast <int&>(a)(int)&a == reinterpret_cast <int>(&a);(int&)a 不经过转换, 直接得到a在内存单元的值,并将其转换成整数输出。(int)a a在内存中的值转换成int类型float类型在内存中存储的形式是 ,符号位 指数 尾数由754标准:阶码采用增码(该数补码的反符号),尾数采用原码所以1.0f 在内存中的形式为0011 1111 1000 0000 0000 0000 0000 0000所以输出的是 0x3f8000000 在内存中的的存储形式0000 0000 0000 0000 0000 0000 0000 0000所以输出的是0x00000000所以前面一个是false,后面一个是true
相关文章推荐
- C语言高手进阶知识点
- 自己收藏的Android开发的知识点各种传送门 持续更新中~~
- C语言一些知识点回顾
- [土狗之路]coursera C语言进阶 习题 运算符判定
- C语言进阶【暑期特别篇】深入剖析(un)signed及溢出(下)
- C语言数组与字符串小知识点
- 我的JAVA学习笔记(记下一些容易忘记的知识点)持续更新
- 单链表常见习题及C语言实现(持续更新)
- hibernate小知识点总结--持续更新
- C语言学习笔记(持续更新)
- OC进阶知识点整理——ARC,Category,block
- 小技术知识点总结[持续更新...]
- C语言推荐书籍及下载(持续更新)
- C语言学习笔记---持续添加中
- C语言进阶:glibc学习之错误处理
- C语言知识点总结
- 开发中的一些杂散乱的知识点(持续添加中..............)
- C语言实现单链表面试题--进阶
- 关于单链表的一些面试题-进阶篇(C语言实现)
- Qt学习重要知识点简记---控件使用篇(持续更新)