一、字符指针变量
我们来看一下下面这段代码:
int main()
{
char a = "012";
char* ptr = &a;
printf("%p\n%p\n%p\n", &a, ptr,&a+1);
return 0;
}
可以看到这里的ptr的实际指向时字符串的首元素地址,而不是我们所通常认为的指向a这个字符串
下面我们再通过剑指offer这本书中收录的一道题来看一下:
int main()
{
char str1[] = "abcdef";
char str2[] = "abcdef";
const char* str3 = "abcdef";
const char* str4 = "abcdef";
if (str1 == str2)
printf("yes\n");
else
printf("no\n");
if (str3 == str4)
printf("yes\n");
else
printf("no\n");
return 0;
}
这是什么原因呢?
str1和str2所指向的是两块不同的空间,所以结果为no
而str3和str4所指向的是同一个地址,当不同的指针指向相同的常量字符串时,会将两块数据放在一个空间内
二、数组指针变量
前面我们已经学习过指针数组,本质是数组,数组的内容是地址,那么数组指针变量是什么呢?、
答:是指针变量
同样我们来看下面这段代码
int main()
{
char a[] = "012";
char* ptr = &a;
printf("%p\n%p\n%p\n", &a[0], ptr, &a[1]);
return 0;
}
同样的道理,在这里的一维数组中,ptr指向的就是数组的首元素地址而非整个数组。
三、二维数组的传参本质
首先我们来看一下在之前的方法中我们是如何传递参数的:
void sys(int arr[][5])
{
}
int main()
{
int arr[][5] = { {1,2,3,4,5},{2,3,4,5,6} };
sys(arr);
return 0;
}
实参和形参都是使用的二维数组的方式来进行传递的。
那么使用指针来进行穿的又是如何传递的呢?
void sys(int* arr[5])
{
}
int main()
{
int arr[][5] = { {1,2,3,4,5},{2,3,4,5,6} };
sys(arr);
return 0;
}
这里所使用的形参int * arr[5] 的意思就是传递了arr这个二维数组
arr[5]指向数组每行有多少列,* 指针指向的是数组的首元素地址,二维数组的首元素就是第一行的地址。我们通过图像来观察一下 :
二维数组看似是这种的形式,但实际上他们在内存中存在的形式是这样的
他们是连续存在的,而二维数组的首元素指向的就是第一行的地址,此时当我们将数组arr+1时,指针指向的内容就会跳过一个一维数组,来到第二个数组的地址