内存地址的基本单位是字节,这也是为什么char,int这些类型都是按照几个字节几个字节这样算的原因。
心中默念3遍,字节字节字节,但凡是指针全部都看字节就行,不要在想几位,什么4字节就是32位,这样想容易乱。
int a;
int *p = &a;
*p 等价于 a 等价于 *(&a)
指针初始化不给初值的话是随机值,如果初始化为NULL,即int *p = NULL;那么地址是0。
给指针变量赋值必须是地址常量或者指针变量,其他数没有意义。
类型也要相同,比如int型变量地址只能赋予int型指针变量
指针占用几个字节?
答:指针其实就是地址,地址是几个字节,那么指针或者指针变量就是几个字节,而地址几个字节,取决于你的操作系统。比如32位的操作系统,那么操作系统和内存就是有32根地址线来寻址,那么他就是32÷8 = 4个字节。而如果是64位操作系统,则的8个字节。但是经过试验,发现我64位的windows中编译的地址也是4个字节,其实这是因为编译器为了兼容系统,都弄成4字节了,但这个是可以设置的。
指针运算,指变量针如何运算呢?
答:指针变量加减法和你这个变量的类型有关,如果是int型的指针变量,比如这个指针地址原来是0x00ffff00,如果对他加1,那么久编程0x00ffff04,因为int是4个字节。如果是double,那么就是编程0x00ffff08,因为一个double是8个字节。总结,地址加几就是加几个当前类型的字节数,也就是加了一个“元素”,减法同理。这也与“内存地址的基本单位是字节这句话对于上了”。
两个指针相减的话,得到的是两个指针之间相隔的数据的个数,也就是“咋们两个地址之间有几个int型”这样的意思,不是单纯的 地址量。比如:int型数组a,那么&a[3]-&a[0] =3,而不是3*4=12字节。
指针也可以做关系运算,也就是<,>,>=什么的。
指针在数组的应用:
依据地址加一就是加一个元素,并且,根据数组的地址是连续的原理,那么可以这么用指针。
int a[3] = {1,2,3};
a[0]和*a的内容是1,*(a+1)的内容是2。注意,不能a++,因为数组名是地址常量哦。
在上面的基础追加 int *p;
p=a;
那么在一维数组中 a[x],*(p+x),*(a+x),p[x] 这几个完全等价!多么好玩。
如果是二维数组,那么a[0],a[1]表示的是行号。a是第0行首地址,a+1是第一行首地址。而a[0]+1是第一行的第一个元素。要看懂如下代码。
还可以用指针来声明2维数组,
int (*p)[3];这样,用法和普通二维数组一样,也可以这样p[1][1];,在二维数组中的*改变了指针的性质,从行指针变成了列指针。
int a[] = {1,23,4,2,4,,4,6,7,7,7,78,8,8,6,}; 里面有几个元素呢?可以这么玩:n = sizeof(a)/sizeof(int);
全局变量,static修饰的变量,字符串常量 这三种数据放到静态区,当程序结束后,才释放内存。
字符串和指针的应用:
指针数组:
啥是指针数组?首先,它是一个数组,然后数组的内容是指针,也就是用来存放指针的数组叫指针数组。要会看以下代码。
多级指针:
指向指针的指针就是2级指针,更多的就是多级指针。
void指针:
声明为void*类型的指针可以被任意型的指针赋值,然后强制转换使用。
以下案例中有使用void指针。
小小写一点代码感受一下。
const修饰指针:
将变量给常量化了。
const int *p :const修饰*p。那么*p不能改,但是p可以改。不允许你通过指针改目标。
int * const p :const修饰的是 p,那么p不能改,*p随便改。但是初始化的 时候可以(不初始化p就没有意义了)。可以做如下初始化,比如 int * const p =&m;
还有 const int* const a; 具体看下面代码。