指针和内存(01)
2015-08-26 13:05
218 查看
day 1-1
测试环境:Linux 2.6.32-279.el6.x86_64
测试代码:pointer.cpp
#include <stdio.h> /** * test code: pointer.cpp * test environment: Linux 2.6.32-279.el6.x86_64 * * 总结: * 1. 所有变量在声明时,系统都会为其分配一个内存地址 * 2. 普通变量在内存中存放的是值 * 3. 指针变量在内存中存放的是该指针指向的内存地址 * 4. 指针变量的类型与指针变量所指向的内存空间存储的数据类型无关, * 使用者可以指定所需的类型去读取这些数据 */ int main() { // 声明一个类型为int的变量,且赋值为 17777 int i = 17777; // 声明一个指针变量 ip,ip 指向的内存空间的数据类型为int // 指针变量存放的是其指向的内存地址,而不是值本身,此处 ip 存放的应该是变量 i 的地址 // &i表示取变量 i 所在的内存地址 int *ip = &i; // 声明一个类型为int的变量,且取指针变量 ip 的值并赋值给iv int iv = *ip; // 声明一个指针变量cp,(char*)表示需要按照char类型的读取方式去读取cp指向的内存空间(&i)中存储的数据 // 此处按照char类型去读取 &i 则会对 &i 原来的4个字节进行截断,只读取1个字节的长度 char *cp = (char*)&i; printf("%p: i=%d\n", &i, i); printf("%p: ip=%p\n", &ip, ip); printf("%p: iv=%d\n", &iv, iv); printf("%p: cp=%p, *cp=%c\n", &cp, cp, *cp); return 0; }
编译 && 执行
g++ -g pointer.cpp -O0 -o pointer ./pointer
执行结果
调试过程
day 1-2
测试环境:Linux 2.6.32-279.el6.x86_64
测试代码:swap.cpp
/** * test code: swap.cpp * test environment: Linux 2.6.32-279.el6.x86_64 * 总结: * 1. 在调用函数传参时,传的是变量的拷贝,而不是原始的值 * 2. 在修改指针指向的内存空间存储的数据时,应使用操作符* * 3. 操作引用参数实际操作的是参数所引用的对象 */ /** * 传进来的是main函数中变量a和b的值的拷贝 c1, c2 * 交换的也是值的拷贝,并没有改变a和b内存空间中的数据, * 所以此函数并不能交换a和b的值 */ void swap1(char c1, char c2) { char tmp = c1; c1 = c2; c2 = tmp; } /** * 传进来的是main函数中变量a和b的内存地址的拷贝 cp1, cp2 * 交换的也是内存地址的拷贝,并没有改变a和b内存空间中的数据, * 所以此函数并不能交换a和b的值 */ void swap2(char *cp1, char *cp2) { printf("in swap2: *cp1=%c, *cp2=%c\n", *cp1, *cp2); char *tmp = cp1; cp1 = cp2; cp2 = tmp; printf("out swap2: *cp1=%c, *cp2=%c\n", *cp1, *cp2); } /** * 传进来的是main函数中变量a和b的内存地址的拷贝 cp1, cp2 * 然后通过操作符*来更新内存地址中的数据,所以此函数可以成功交换a和b的值 */ void swap3(char *cp1, char *cp2) { printf("in swap3: *cp1=%c, *cp2=%c\n", *cp1, *cp2); // 取c1指向的内存空间中的数据赋值给临时变量tmp char tmp = *cp1; // 取cp2指向的内存空间中的数据赋值到cp1指向的内存空间中,覆盖原有数据 *cp1 = *cp2; // 将tmp的值赋值到cp2指向的内存空间中,覆盖原有数据 *cp2 = tmp; printf("out swap3: *cp1=%c, *cp2=%c\n", *cp1, *cp2); } /** * 传进来的是main函数中变量a和b的引用cr1, cr2 * cr1, cr2直接操作的是其引用的对象,所以此函数可以成功交换a和b的值 */ void swap4(char &cr1, char &cr2) { char tmp = cr1; cr1 = cr2; cr2 = tmp; } int main() { char a = 'A'; char b = 'B'; printf("origin: a=%c, b=%c\n\n", a, b); swap1(a, b); printf("swap1: a=%c, b=%c\n\n", a, b); swap2(&a, &b); printf("swap2: a=%c, b=%c\n\n", a, b); swap3(&a, &b); printf("swap3: a=%c, b=%c\n", a, b); // 重置 a, b 为swap3交换之前的原值 a = 'A'; b = 'B'; swap4(a, b); printf("swap4: a=%c, b=%c\n", a, b); return 0; }
编译 && 执行
g++ -g swap.cpp -O0 -o swap ./swap
执行结果:
扫盲:
[k&r第1章第8节] In C, all function arguments are passed “by value.” This means that the called function is given the values of its arguments in temporary variables rather than the originals.意思就是说在c语言里,所有的函数传参都是通过值传递:调用函数的时候传递过去参数值都是存放在临时变量中,而不是存放在原来的变量中。
所以在调用函数的时候,会根据参数列表创建相应的一些临时变量,然后将参数的值拷贝一份到临时变量中,也就是说被调用的函数不能直接修改主调函数中变量的值。
分析过程:
变量a和b的在内存中的情况:swap1中各个变量在内存中的情况:
调用swap1(char c1, char c2)时,会产生和变量a, b对应的临时变量c1, c2(注意观察上图,这两个变量所占的内存空间的地址明显和a, b不一样),然后系统会将a, b的值分别赋值给c1, c2,此时不管swap1中如何操作c1, c2,都不会影响main函数中的变量a, b的值。
-gdb调试过程:
swap2中各个变量在内存中的情况:
在调用swap2(char *cp1, char *cp2)时,会产生对应的两个临时指针变量cp1, cp2,然后系统会将&a, &b的值分别赋值给c1, c2,后续的一些操作在交换的是cp1和cp2指向的地址,并没有操作cp1和cp2指向的地址的值,因此不会影响main函数中的变量a, b的值。
-gdb调试过程:
swap3中各个变量在内存中的情况:
在调用swap3(char *cp1, char *cp2)时,
会产生对应的两个临时指针变量cp1, cp2,程序会将&a, &b的值分别赋值给cp1, cp2
使用*cp1读取到cp1指向的内存空间中的数据赋值给临时变量tmp,此时tmp的值变为变量a的值
使用*cp2读取到cp2指向的内存空间中的数据(b的值),并将数据写到cp1指向的内存空间(&a)中,
覆盖掉原来的数据(原来存放的是变量a的值),此时cp1指向的内存空间中存储的就是b的值了,
也就是说变量a里存放的数据变成了变量b的值
将tmp的值写到cp2指向的内存空间(&b)中,覆盖掉原来的数据(原来存放的是变量b的值),此时cp2
指向的内存空间中存储的就是tmp的值了,也就是说变量b里存放的数据变成了最开始的变量a的值
-gdb调试过程:
swap4中各个变量在内存中的情况比较简单,就不画图了,直接上gdb调试的图:
-gdb调试过程:
相关文章推荐
- 关于指针的一些事情
- IE7降低内存和降低CPU的几个技巧
- 如何高效的使用内存
- DOS下内存的配置
- XP/win2003下发现1G的内存比512M还慢的解决方法
- PowerShell实现动态获取当前脚本运行时消耗的内存
- C#实现把dgv里的数据完整的复制到一张内存表的方法
- SQL语句实现查询SQL Server内存使用状况
- C# Pointer指针应用实例简述
- C语言内存对齐实例详解
- C++智能指针实例详解
- C++指向函数的指针实例解析
- 关于c语言指针的两处小tip分享
- 浅析iterator与指针的区别
- 探讨C++中数组名与指针的用法比较分析
- 详解C++中的指针、数组指针与函数指针
- C语言安全之数组长度与指针实例解析
- C++中指向对象的常指针与指向常对象的指针详解
- 指向变量的常指针与指向常变量的指针详细解析
- C#通过指针实现快速拷贝的方法