您的位置:首页 > 其它

指针和内存(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调试过程:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内存 指针 swap