1.指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
2.指针的大小是固定的4/8个字节(32位平台/64位平台)
3.指针是有类型的,指针的类型决定了指针在加减整数的时候的步长,以及指针在解引用操作的时候的权限。
1.字符指针
在指针的类型中我们知道有一种指针类型为字符指针char *;
//字符指针
void test3_31()
{
char ch = 'w';
char *pc = &ch;
const char *p = "abcdef";//把字符串首字符a的地址赋给了p,加上const可以防止后面的字符串被改变
char arr[]="abcdef";//把字符串放到arr数组里
//*p='W';//写入访问权限冲突,"abcdef"是常量
*pc = 'b';
printf("%c\n",ch);
printf("%s\n",p);
}
void test3_32()
{
const char* p1 = "abcdef";
const char* p2 = "abcdef";
char arr1[] = "abcdef";
char arr2[] = "abcdef";
if(p1==p2) //比较的是地址
printf("p1==p2\n");//p1==p2
else
printf("p1!=p2\n");
if(arr1==arr2)
printf("arr1==arr2\n");
else
printf("arr1!=arr2\n");//arr1!=arr2
}
2.指针数组
指针数组是一个存放指针的数组
int* arr1[6] //存放整型指针的数组
char *arr2[5] //存放一级字符指针的数组
char **arr3[4] //存放二级字符指针的数组
//指针数组
void test3_33()
{
int arr1[] = {1,2,3,4,5};
int arr2[] = {2,3,4,5,6};
int arr3[] = {3,4,5,6,7};
int* parr[3] = {arr1,arr2,arr3};//存放三个指向不同数组的指针
int i = 0,j = 0;
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
//*(p+i)等价于p[i]
printf("%d ",*(parr[i]+j));
//printf("%d ",*(*(parr+i)+j));
//printf("%d ",parr[i][j]);
//printf("%d ",(*(parr+i))[j]);
}
printf("\n");
}
}
3.数组指针
数组指针是指向数组的指针
int (*p)[10];
p先和*结合,说明p是一个指针,指针指向一个大小为10个整型的数组,所以p是一个数组指针。
要注意的是[ ]的优先级是高于*号的,所以必须加上括号来保证p先与*结合。
//再次讨论数组名
void test3_34()
{
int arr[10]={0};
int sz = 0;
int* p = arr; //整型指针存放数组首元素地址,p的类型是int *
int (*p2)[10] = &arr; //数组指针存放数组地址,p2的类型是int (*)[10]
//整型指针是用来存放整型的地址
//字符指针是用来存放字符的地址
//数组指针是用来存放数组的地址
//地址加1跳过4个字节
printf("%p\n",arr);//0019FEB4
printf("%p\n",arr+1);//0019FEB8
//地址加1跳过4个字节
printf("%p\n",&arr[0]);//0019FEB4
printf("%p\n",&arr[0]+1);//0019FEB8
//地址加1跳过40个字节
printf("%p\n",&arr);//0019FEB4
printf("%p\n",&arr+1);//0019FEDC
sz = sizeof(arr);
printf("%d\n",sz);//40
}
//数组名通常表示的都是数组首元素的地址
//但有2个例外:
//1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
//2.&数组名,这里的数组名表示的依然是整个数组,所以&数组名取出的是整个数组的地址