(一)什么是指针?
指针类型:存放内存单元地址的变量类型。
指针变量:存储地址的变量。
常将地址变量、地址、地址变量的值统称为指针。
(二)定义与使用
1、指针变量的定义
格式: 数据类型 * 变量名;
- 数据类型:可以是基本数据类型、构造数据类型、void类型;
- 指着变量无论指向什么类型的对象,存的都是地址,存储空间大小均为4个字节
如:
int * ip;
float *fp;
typedef int A[10];
A *ap;
对上面的哥哥变量,有: sizeof(ip) = sizeof(fp) = sizeof(ap) = 4;
虽然存储空间都一样,但是不同类型的指针变量存不同类型的变量;
2.初始化与赋值
若指针变量既没有赋值,也没有初始化,那它存的地址是一个随机数,可能指向的内存单元中放着及其重要的数据,若对它访问可能对系统造成极大的危害。所以指针在使用之前必须有确定的指向!即赋值后再引用!
格式:
定义时: 数据类型 * 指针变量名 = 初始地址表达式;
定义后: 指针变量名 = 地址表达式;
赋值时应注意:
1)不能将非地址常量、变量及无意义地址赋值给指针变量。
2)可用一个已初始化的地址指针给另一个指针赋值。但类型必须一致,不一致时可进行强制转换!
如:
char *p = NULL;
int * ip = (int *) p + 100;
3)void类型的指针可以存放任意的变量地址,但void类型给其他类型赋值时必须强制转换;
如:
void v ;
void *vp;
int *ip,i;
vp = &i;
vp = ip;
ip = (int *)vp;
3.指针运算
1) * 和 & 运算
* 出现在指针变量表达式前时 ,是一元运算符,表示访问指针所指向的对象;
& 在变量左边,一元运算符,表访问变量的地址。
2)加减法
表示指针向后或向前移动 n 个sizeof(数据类型) 长度的存储单元。
3)自增和自减移动
表从当前位置向后或向前sizeof(数据类型) 长度的存储单元
注意:
int * p , * q, a = 5;
p = &a;
p++;//指针p后移4个字节;
*p++; // 顺序即 *p, p++;
(*p)++;// 读取p指向的变量,使变量值+1;
* ++p;// 顺序即: ++p, *p;(指针后移,再取值)
++ *p;//将p指向的变量的值+1;
4)指针相减:
指向同一数组时才有意义;
表量指针间数组元素的个数;
5)两个指针的比较
一般用于下面两种情况:
一是比较两指针对象内存的位置关系;
二是判断是否为空指针。
(三)指针与字符串
如:
char str[5] = "abcd"; //str[]中的5个元素分别是:'a','b','c','d','\0';
char *p_str = "abcd"; //p_str 的值为'a'的地址
1)字符数组名与字符指针名等效:
如cout << str << endl;与cout << p_str << endl;均可输出字符串
注意:
- 字符类型以外的数组或指针,使用cout 输出的是地址,而不是字符串。
若想输出字符数组的地址与字符指针的地址,可将其强制转化为void指针,如cout << (void *)str << endl;
cout << (void *) p_str << endl;
- 空指针与指向空串的区别;
(对空指针的引用是危险的)
char * p1 = NULL; // 空指针
char *p2 = 0;// 空指针;
char *q1 = "\0";//空串!
char *q2 = '\0' ; // 空指针!!!
2)可以将字符指针当字符数组使用
如*(p_str+1) 和p_str[1]等效
- 对指针指向的字符串赋值不能简单用“=”
如:char * p = "1234"
char *q = "abcd"
q = p;// 只是将q指向p所指的地址;
可用下面的方法进行赋值:
while(*q)
{
*p++ = *q++;
*p = '\0';
}
(四)指针与数组
1.使用指针操作符*存储地址
1)a[i] 等效于*(a+i)
2)b[i][j][k] 等效于 *(*(*(b+i)+j)+k)
2.指针数组
以指针变量为元素的数组
定义的格式: 类型名 * 数组名[下标表达式];
如 int * p_a[5];
typedef int * I_P;
I_P p_a[5];
char * sentence[] = { " I'm",
"a,Chinese"
}
(可采用二位数组的方式存取)
3.数组指针
指向数组的指针
定义的格式: 类型名 ( * 指针名)[下标表达式];
如:
int (*a_p)[5];
typedef int I_A[5];
I_A *a_p;
注意类型匹配
int a[5];
a_p = &a;
4.多重指针
定义格式: 类型名 * * 变量名
(二级指针)
如: int ** p
等价于 :
typedef int *P;
P *p;