1、指针变量:
上图:定义了一个 int a 并赋值一个 10,右边显示的是他的内存模型,内存地址0x100这个位置存储了一个数值 10;变量名是一个标识符,编译时会转换为变量所在内存空间的地址。我们可以获取到变量的地址 ,通过**&a 取址操作符**可以在程序运行时获取到变量的内存地址。我们还可以让其他变量来使用这个地址的值,使用指针可以做到。下面是指针的使用:
声明指针变量:
指针变量和普通的变量存储的数据不一样,指针变量只能用来存储指针,指针也就是地址;指针变量存储的数据是地址,不能是其他变量的数据值;指针变量声明使用 * 表示是一个指针变量;
int *p; //指针变量的声明
定义指针变量:
int *p;
int a = 10;
*p = &a;
通过&取址符号把变量 a 的地址赋值给 指针变量 p;
上图是指针变量的内存模型,可以看到指针变量存储是a的地址;
指针变量在内存中也占用内存空间,在32为系统中指针变量占用的字节大小是4字节,在64位系统中指针变量占用的大小是8字节;指针占用系统的字节数和指针变量的类型无关,假设在32位系统中:不管什么类型的指针都占用4字节
int a = 100;
int *pi = &a;
char *pc;
long long *pll;
printf("%d\n",sizeof(pi)); //4
printf("%d\n",sizeof(pc)); //4
printf("%d\n",sizeof(pll)); //4
声明时初始化:
指针变量在局部变量中声明时,初始化默认值是随机的,指向未知的空间地址使用可能会有风险,称之为垃圾值。所以为了保险起见在声明指针变量时我们直接进行初始化。或者初始化为NULL
int a = 10;
int *p = &a; //声明时初始化
cout<<*p<<endl; //输出 10
声明在函数内部的变量(局部变量),默认值都是未知垃圾值;但是声明在全局变量的变量,默认值都为 0 ,全局指针变量的默认值为 0 就等价于 int *p = NULL;
cout<< * p<<endl;里面的*p 表示解引操作,*解引用操作符返回指针指向的变量,然后进行输出。
指针修改变量的值:
int a = 100;
int *p = &a;
*p = 100; //解引后为指向的地址赋值,也就是为变量a赋值
printf("%d",*p);
*p 解引返回指向的变量,给变量赋值100;
空指针:
关键字:NULL
一个指针变量只进行了声明,但是没有定义还没有使用到,我们可以将它初始化为空指针,可以防止指针的误操作。可以表示指针不指向任何有效地址;
int *a = NULL;
NULL 是一个宏,定义在stddef.h,stdlib.h,stdio.h头文件中。定义如下:
#define NULL ((void *) 0)
使用 0 也表示指针不指向任何有效地址,和NULL差不多
int *a = 0;
他们都是表示空指针的方式,
快速读指针:
从右往左读,请看下面的指针;
const int *p;
p 是一个变量
*p 是一个指针变量
int *p 是一个指向int类型的指针变量
const int *p 是一个指向int类型常量的指针变量
2、常量与指针
指向常量的指针
看名字我们就知道这个指针是用来指向常量的,常量是不允许初始化后再次修改的,指向常量的指针自然也不能去修改指向的常量;
const int *p;
//两种写法等价
int const *p;
指向常量的指针 也可以 指向非常量 , 指向常量的指针 不可以 修改指向的地址的值,指向的是 非常量 也不能修改。
const int num = 100;
const int *p = #
int num = 100;
const int *p = &a; //指向常量的指针可以指向非常量
*p = 200; //报错 指向常量的指针不可以修改指向地址的数据
特点:指向常量的指针,不可以修改指向的地址的数据,可以修改本身的变量(可以修改指向的地址)
指向非常量的常量指针
先来理解“ 指向非常量的常量指针 ”的字面意思, 首先 他是一个常量指针说明这个指针存储的值是不能修改的(指针变量存储的值是地址,意味着存储的值不能修改),然后他是用来指向非常量的指针,说明只能指向非常量。
int num = 10;
int * const p = #
”指向非常量的常量指针“ 指向 常量
是不允许的,不能指向常量,因为非常量指针可以修改指向的地址的值,常量是不允许修改值的,这个指针指向常量也没用,编译器会报错。
const int a = 10;
int *const p = &a; //报错
cout<<*p<<endl;
特点:指向非常量的常量指针,不可以修改指针本身变量值,可以修改指针指向的指针(指针本身就是一个常量所以不能修改)
指向常量的常量指针
const int a = 10;
const int * const p = &a;
这个指针具有上面两种指针的特点;
通过字面意思理解: 首先他是一个 常量指针说明本身的值不能修改,然后他还是一个指向常量的指针,说明他指向的是常量数据不能被修改。
特点:指向常量的常量指针,指向的地址的数据不能被修改,指针本身也不能被修改
总结:
1.const int *p; 是一个指针用于指向常量
2.int * const p ; 是一个常量指针,本身是常量
3.const int *const p; 是一个常量指针,也是一个指向常量的指针
1.const 后面跟 *p ,*p可以看作是解引用操作,所以const 修饰的是指针指向的数据,这个数据不能被修改(指向常量的指针)
2.const 后面跟 p ,没有解引用 ,所以const 修饰的是指针本身,这个指针可以指向非常量(指向非常量的常量指针)
2.const 后面跟 * 还跟了 p 这个指针指向的数据不能改变,指针本身特不能改变; (指向常量的常量指针)
指向非常量的常量指针 和 指向常量的常量指针 两个共同点都是常量指针,指针本身不能被修改;