C/C++常识
2015-12-17 00:31
363 查看
1.局部变量和数组在内存栈结构中的分配细节
内存中的分配图如下:
2.浮点数的二进制表示
以float为例,如下
看输出结果
是不是感觉结果在预测之中,但却一下子反应不过来?看着下图就明白了
float的二进制表示:
再来点更直观的
输出结果
3.字节对齐
自然对齐:
对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。
为什么要字节对齐:
需要字节对齐的根本原因在于CPU访问数据的效率问题。比如地址为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002-0x00000003的一个short,第二次取从0x00000004-0x00000005的一个short然后组合得到所要的数据,如果变量在0x00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为char,然后组合得到整型数据。而如果变量在自然对齐位置上,则只要一次就可以取出数据。
在VS工程属性->代码生成->C/C++->结构体成员对齐中可以设置具体几字节对齐。
对于上面的结构体mystruct选用1字节对齐,可以看到结构体内部变量的地址紧密排列
4字节对齐,对应于32位cpu
8字节对齐,对应于64位cpu
4.++i和i++
输出结果
5.const相关
6.static相关
不论 my_fn函数调用多少次,static bool my_var_initialized = false;只在第一次调用时候执行。
7.extern相关
extern关键字中是否extern int *p;能指向int p[5] = {100,123};
原因在于,指向类型T的指针并不等价于类型T的数组extern int *p ;说明p是一个指针变量而不是数组,因此与实际的定义不同,从而造成运行时非法访问
如上面这样写运行就会出错,应该extern int p[];
8.结构体
可以正常运行,输出10;声明结构体struct bar{};
结构体的类型为bar;
此时在c语言声明结构体变量struct bar b;
在c++中可以只用bar b;
声明struct bar{} bar;
此时在声明结构体类型bar的同时声明一个结构体变量bar;
此时在c++中也只能用struct bar b;声明另外的结构体变量
不能正常运行,具体原因还不是很清楚
#include <stdio.h> #define ARRAY_SIZE 10 void natural_numbers(void) { int i; int array[ARRAY_SIZE]; i = 1; while (i <= ARRAY_SIZE) { array[i] = i - 1; i = i + 1; } } int main(){ natural_numbers(); printf("end"); }
内存中的分配图如下:
2.浮点数的二进制表示
以float为例,如下
#include <iostream> #include <iomanip> using namespace std; void main() { float x = 1.3; float y = 0.4; cout << setprecision(10) << x<<endl; cout<<setprecision(10) <<x + y<<endl; if (x + y != 1.7) cout << "addition failed?" << endl; }
看输出结果
1.3 1.7 addition failed? 请按任意键继续. . .
是不是感觉结果在预测之中,但却一下子反应不过来?看着下图就明白了
float的二进制表示:
再来点更直观的
#include <iostream> #include <iomanip> using namespace std; void main() { float x = 1.3f; float y = 0.4; cout << setprecision(10) << x<<endl; cout<<setprecision(10) <<x + y<<endl; }
输出结果
1.299999952 1.699999928
3.字节对齐
自然对齐:
对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。
为什么要字节对齐:
需要字节对齐的根本原因在于CPU访问数据的效率问题。比如地址为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002-0x00000003的一个short,第二次取从0x00000004-0x00000005的一个short然后组合得到所要的数据,如果变量在0x00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为char,然后组合得到整型数据。而如果变量在自然对齐位置上,则只要一次就可以取出数据。
在VS工程属性->代码生成->C/C++->结构体成员对齐中可以设置具体几字节对齐。
int main() { struct { char a, b; double d; int i; } mystruct; int e = 0; return 0; }
对于上面的结构体mystruct选用1字节对齐,可以看到结构体内部变量的地址紧密排列
4字节对齐,对应于32位cpu
8字节对齐,对应于64位cpu
4.++i和i++
#include <stdio.h> int main(){ int x=0,y=0; int a[5]; int b[5]; a[x++]=5; b[++y]=5; printf("x=%d,y=%d,a[0]=%d,a[1]=%d,b[0]=%d,b[1]=%d",x,y,a[0],a[1],b[0],b[1]); return 0; }
输出结果
x=1,y=1,a[0]=5,a[1]=2686868,b[0]=1982493216,b[1]=5
5.const相关
const int limit //整型变量limit不可二次赋值 const int *p //指针p指向的变量只读,p可以指向不同变量 int* const p //指针p指向的变量可以修改,p不能改变
6.static相关
int my_fn() { static bool my_var_initialized = false; if (my_var_initialized) printf("已初始化"); my_var_initialized = true; }
不论 my_fn函数调用多少次,static bool my_var_initialized = false;只在第一次调用时候执行。
7.extern相关
extern关键字中是否extern int *p;能指向int p[5] = {100,123};
原因在于,指向类型T的指针并不等价于类型T的数组extern int *p ;说明p是一个指针变量而不是数组,因此与实际的定义不同,从而造成运行时非法访问
int main(){ extern int *p; extern int a; printf("%d\n", a); printf("%d\n", p[1]); } int p[5] = {100,123}; int a = 100;
如上面这样写运行就会出错,应该extern int p[];
8.结构体
int main(){ struct bar { int b; } bar; bar.b= 10; printf("%d\n",bar.b); }
可以正常运行,输出10;声明结构体struct bar{};
结构体的类型为bar;
此时在c语言声明结构体变量struct bar b;
在c++中可以只用bar b;
声明struct bar{} bar;
此时在声明结构体类型bar的同时声明一个结构体变量bar;
此时在c++中也只能用struct bar b;声明另外的结构体变量
int main(){ struct bar { int bar; } bar; bar.bar= 10; printf("%d\n",bar.bar); }
不能正常运行,具体原因还不是很清楚
相关文章推荐
- 运算符重载编程题2(C++程序设计第4周)
- 运算符重载编程题1(C++程序设计第4周)
- C语言之变量、常量(define\const)、变量的声明和定义
- 【C语言提高33】数组指针类型定义
- c语言:日本某地发生了一件谋杀案,写一个程序来确定到底谁是凶手。
- c语言:在屏幕上打印杨辉三角。
- 算法导论第十六章——贪心算法.(C++版本)
- 【LeetCode】20 Valid Parentheses (c++实现)
- Release版本下pthread_mutex_t死锁分析
- 八皇后问题
- 【LeetCode】205 Isomorphic Strings (c++实现)
- 位域所占空间的大小
- leetcode笔记:Longest Substring Without Repeating Characters
- 【C语言提高32】数组类型
- 实战c++中的vector系列--可怕的迭代器失效之二(删除vector中元素)
- 实战c++中的vector系列--可怕的迭代器失效之二(删除vector中元素)
- C语言点滴
- 功能测试机设计-MFC and C++ 以及单片机 C
- 【C语言提高31】数组基础概念
- C++ 泛型算法