先复习复习(点击进入) -> 指针基础
先把握以下几个概念:
- 指针就是个变量,用来存放地址,地址唯一标识一块内存空间
- 指针的大小是固定的,32位平台位4个字节大小,64位平台位8个字节大小
- 指针有类型,指针的类型决定了指针+或者-整数的步长,指针解引用操作的时候的权限
- int a = 10;
int *pa = &a;
p的值为 a的地址
*p的值为 p所指向空间的值,即 *p= 10
&p的值为指针变量 p的地址
字符指针就是指向字符的指针:char*;
void main()
{
char ch = 'a';
char* pch = &ch;
*pch = 'w'; //修改字符ch的值为w
}
观察以下两种定义方式:
char str1[] = “abcd”;
char *str2 = “abcd”;
上面定义str1与受str2都可以称为“字符串”,但是两者却有着本质的区别:
- char str1[] = “abcd”;
- 应该称str1为一个字符数组
- 运行可知sizeof(str1) 的值为5
- 本质是开辟了一块大小为5字节的内存空间,该内存空间的名字为str1,空间内存放’a’, ‘b’, ‘c’, ‘d’, ‘\0’
- char *str2 = “abcd”;
- 应该称str2为字符指针
- 运行可知sizeof(str2) 的值为4(32位平台)
- 本质是将“abcd”的首字符的地址放入了str2中,“abcd”是一个常量字符串,不能通过指针去修改其值
下面,请仔细观察下面代码:
void main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
char* str3 = "hello bit.";
char* str4 = "hello bit.";
if (str1 == str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if (str3 == str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
}
该代码的输出结果是:
str1 and str2 are not same
str3 and str4 are same
出现这个结构的原因如下:
str1与str2都是字符数组,只是用相同的常量字符串进行了初始化,但是两者所开辟的内存块不同;
str3与str4都是字符指针,两者指向的是同一个常量字符串,C语言/C++会将常量字符串存储到单独的一个内存区域,当几个指针指向同一个字符串的时候,他们是机会指向同一块内存。
指针数组 – 是数组,是存放指针的数组
int *arr1[10]; //存放整型指针的数组
char *arr2[4]; //存放字符指针的数组
char **arr3[5]; //存放二级字符指针的数组
数组指针 – 是指针,是指向数组的指针
- int *arr1[10]; //指针数组
- int (*arr2)[10]; //数组指针
可以看出arr1与arr2的区别就是一对小括号 () ;
那如何理解呢?
先看一段代码:
void main()
{
int arr[] = { 1,2,3,4 };
printf("%p\n", arr);
printf("%p\n", &arr);
}
通过运行可以发现,&arr与arr打印出来的值是一样的,都是首元素的地址。但是两者的含义一样吗?
当然不一样!
为了验证两者是不同的,先来看下面一段代码:
void main()
{
int arr[] = { 1,2,3,4 };
printf("arr: %p\n", arr);
printf("arr+1: %p\n", arr + 1);
printf("&arr: %p\n", &arr);
printf("&arr+1: %p\n", &arr + 1);
printf("%d", sizeof(arr));
}
运行之后发现,arr+1只增加了4个字节,而&arr+1增加了16(十六进制的10是十进制的16)个字节。
arr与&arr的值虽然一样,但是含义不一样
- arr的值是数组首元素的地址,arr+1就是数组第二个元素的地址
- &arr标识的是整个数组的地址,&arr+1,也就是数组的地址+1,跳过整个数组的大小,数组的大小为16,所以&arr+1相对于&arr的差值为16.
void main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
int(*parr)[10] = &arr; //把数组arr的地址赋值给指针变量parr
}
void print_arr1(int arr[][3], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void print_arr2(int (*parr)[3], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
}
void main()
{
int arr[5][3] = { 1,2,3,4,5,6,7,8,9,10 };
print_arr1(arr, 5, 3);
printf("\n---------------\n");
print_arr2(arr, 5, 3);
}
最后,来看看下面代码的含义吧:
int arr[5]; //整型数组
int *parr1[10]; //指针数组
int (*parr2)[10]; //数组指针int (*parr3[10]) [5]; //数组指针数组
是一个数组,该数组存放的是指针,存放的指针指向的是整型数组