1、指针和地址
在vs中进行调试,代码中的注释为调试所看的结果。
#include <iostream>
using namespace std;
int main()
{
int a = 10;//a 的地址0x00D7FBD0 a的值是10;
int* b = &a; //b 的地址0x00D7FBC4, b的值是a的地址
return 0;
}
在内存中,变量a
所代表的即是某块地址,里面存储的是变量。&
取地址符号,可以对左值取地址,声明一个指针变量,可以存储所取到的地址值,当然也可以去知道指针的地址,但是很多时候没有必有。
2、数组首地址和数组名取地址
我们 查 a 、&a 、&a[0] 是一样的值。
-
事实上a和 &a结果都是数组的首地址。但他们的类型是不一样。
-
a表示&a[0],也即对数组首元素取地址。a+1,也即是 &a[1]。
-
&a尽管值为数组首元素地址。但类型为:类型 (*)[数组元素个数],所以&a+1大小为:首地址+sizeof(a)。
以上面的代码为例,我们可以查一下&a+1,所指的内容是a[4]后面的首地址。
应该在了解数组名即是数组的首地址的同一时候,也要知道,数组名仅仅是“相当于”指针,而并不是真的是指针,
数组名是仅仅是个常量(一个值为数组首元素地址的常量),所以不能进行++或者–运算。 而常量更是无法取地址的,而之所以有&a,事实上这里的a的意义早已经不是当初那个数组名了,它此时代表了整个数组。
#include<stdio.h>
#include <iostream>
using namespace std;
int main()
{
int a[5]={0x11121314,0x21222324,0x31323334,0x41424344,0x51525354};
printf("%p\n%p\n",a,&a); //数值相等
//输出为 00AFFA5C 00AFFA5C
cout<<sizeof(a)<<endl; // a是复合类型 int[5]
// 输出20
cout<<sizeof(&a)<<endl; // &a是int(*)[5]
// 输出4
cout<<sizeof(a+1)<<endl; // a+1 变成指向数组第二个元素的指针,其类型是 int *
//输出4
cout<<sizeof(&a+1)<<endl; // &a+1 还是 int(*)[5]。类型还是指针
//输出4
//a+1 由于 a 指向int(但不是普通指针),加1移动int个大小
//&a+1 由于 &a 指向 int[5],加1移动 int[5] 个大小
printf("%p\n%p\n",a+1,&a+1);
//00AFFA60(00AFFA5C+4) 00AFFA70(00AFFA5C+5*4)
}
记录一下,由上面我们知道,数组名可以在一定程度上当作指针去访问,因此产生些许疑问,那么类,结构体,普通数据类型 的名字有什么区别。
#include <iostream>
#include <stdio.h>
using namespace std;
struct stu{
int age;
char b;
};
class A{
public:
int aa;
int ss;
A(int a, int s):aa(a),ss(s){}
void set(){
cout << "hello world" << endl;
}
};
int main()
{
A aaa(7,3);
A* ccc = &aaa;
printf("%p\n", aaa);
printf("%p\n", &aaa);
printf("%p\n", ccc);
cout << endl;
int f = 7;
printf("%p\n", f);
printf("%p\n", &f);
cout << endl;
stu s;
s.age = 7;
s.b = 'a';
printf("%p\n", s);
printf("%p\n", &s);
stu* sz = &s;
printf("%p\n", sz);
cout << endl;
int a[10] = {0};
int* b = a;
printf("%p\n", a);
printf("%p\n", &a);
printf("%p\n", b);
return 0;
}
从上面的结果,我们暂且可以将类,结构体,普通数据类型看成一个样子,其中类和结构体的名字,可以取其地址,地址为相应其的首地址。而数组名,有一定作用,可以当指针用。
c++写链表时new生成的节点在程序结束时需要释放吗
不是要在程序结束时释放,是在一个节点不再需要的时候就释放。
比如删除一个节点,不只是把它从链表移除,还有delete它。
之所以要这么做是因为你如果不手动delete它,知道程序结束前,它会继续占用内存,如果是一个大程序,这样运行久了,可能内存就没了。
程序结束的时候是不用释放的,因为系统会回收这些内存。