目录
一.字符指针
我们先了解一下指针的概念
1.指针就是一个变量,用来存放地址,地址唯一标识一块内存空间。
2.指针的大小是固定的,32位平台是4个字节,64位平台是8个字节。
3.指针是有类型的,指针的类型决定了指针的+-整数的步长,也决定了指针解引用操作的访问权限。
4.指针的运算(指针+-整数,指针-指针,指针的关系运算)
字符指针的类型位char*。
① int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
② int main()
{
const char* pstr = "hello";
printf("%s\n", pstr);
return 0;
}
一些人可能认为第二个是把“hello"放到了pstr指针变量里了,其实不然,它是把"hello"字符串首元素地址(就是h的地址)放到了pstr指针变量里了,pstr指向这个字符串。
下面我们来分析这段代码
#include <stdio.h>
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
const char* str3 = "hello bit.";
const 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");
return 0;
}
解析:编译器会把常量字符串存储到单独的一块区域(常量区),当几个指针指向同一个字符串的时候,实际上指向的是同一块内存。用相同的字符串初始化不同的数组的时候就会开辟出不同的内存块。
二.指针数组
顾名思义,指针数组是一个存放指针的数组。
int* arr1[10]; //存放整形指针的数组
int* arr2[4]; //存放一级字符指针的数组
int* arr3[5]; //存放二级字符指针的数组
举个使用指针数组的例子
parr是一个存放三个指针的指针数组,*(parr+i)可以拿到parr数组存放的地i个元素,可能是arr1或者arr2或者arr3,因为这三个都是数组名,表示首元素地址,指向第一个元素,所以*(parr+i)+j就可以指向三个数组第j个元素,解引用就可以访问这个元素。
三.数组指针
1.数组指针的定义
数组指针是指向数组的指针。
int* p1[10]; //指针数组
int (*p2)[10]; //数组指针
p2和*结合,说明p2 是一个指针,指向一个大小为10个整形的数组。
注意:[]的优先级高于*号,所以要加上()来保证p2和*先结合。
2.&数组名vs数组名
arr是数组名,表示首元素地址。
了解&arr是什么之前,我们先看一下下面的代码。
&arr+1比&arr大40个字节,通过上面的代码我们可以知道&arr其实是数组的地址,+1跳过整个数组。
3.数组指针的使用
printf_arr2函数中的arr+i是第i行的地址,*(arr+i)相当于拿到了第i行,也相当于第i行的数组名,数组名表示首元素地址,即第i行第一个元素的地址,所以*(*(arr+i)+j)相当于拿到了第i行第j个元素。
tip:
int (*parr[10])[5]表示什么意思呢?
parr是一个数组,数组有10个元素,每个元素都是int (*)[5]类型的,所以parr是一个存放数组指针的数组。
四.数组传参和指针传参
1.一维数组传传参
2.二维数组传参
3.一级指针传参
4.二级指针传参
🙇感谢大家的阅读,如有错误请指出,我们下次再见。