那些年被误解的指针和数组
误解1: &运算符返回一个地址
解释: &叫做取址运算符,运算的结果是返回一个指向某个数据类型对象的指针。
int a=1; int *p = &a;
&a不是地址,通过&运算符获取a的地址,并返回一个指向a的指针,&a是指向a的指针,不是把地址给指针变量p,而是把指针直接赋值给变量p
误解2: 数组和指针一样
解释: 数组是一种数据结构,包含了一些同一类型数据的组合内存空间,指针是指向某一个数据类型的地址,之所以误解是因为数组作为表达式时会隐适转换为指向首元素的指针,除了&和sizeof以外。
误解3: 数组名是常指针,所以不可赋值
解释: 数组名是数组的标识符,代表的数组,跟指针没关系。之所以不能赋值,因为数组是不可修改的左值。误解为指针因为数组作为表达式时大多数情况会隐适转换为指向首元素的指针
误解4:数组名不是左值,所以不可以赋值
解释: 上面就说了,数组名是数组的标识符,之所以不能赋值,因为数组是不可修改的左值,左值包含了可修改左值和不可修改左值。
误解5:&数组名 是指针的指针或者说二级指针
解释: 数组用于&不会转换为首元素的指针,代表的本来的意思:数组。当使用&和sizeof ,这个时候数组名代表的是数组,&数组名是指向该数组的指针,结果是一个右值表达式。
误解6:指针是变量
解释: 指针变量只不过用来存放指针,是指针的标识。指针类型是一种对象的数据类型,就像int类型一样。
误解7:下标运算符[] 用于数组。
解释: 下标运算符定义为用于两个操作数,其中一个操作数为指针,另一个操作数为Int整型类型。当我们用数组名[],其实数组名已经转换为了指针使用。
数组作为表达式大多会隐适转换为指针,有几种例外
int arr[]={1,2,3,3};
1、用于sizeof 运算符
sizeof arr 得到数组的大小 16个字节,说明arr解释为数组,不然是指针的话,就是地址大长度了,64位系统下8字节
2、用于&运算符
&arr类型是 int (*)[4],指向一个数组的指针,所以arr是解释为数组,&arr+1,指针前进整个数组的长度,前进16个字节
3、用于typeof运算符
typeof用于获取数据类型,是C23下新加的运算符。typeof(arr) newArr={2,3,4,5} ,获取arr的类型 并声明newArr数组,类型是int [4]
4、用于初始化char[]类型数组的字符串字面量
字符串字面量也就是"hello" 这种双引号的字符序列,因为它是char []类型,所以属于数组。用于初始化另一个char []类型数组变量时,不会隐适转换
char arr[] = {"hello"} 花括号可以不加。“hello”字符数组,初始化arr数组,未发生转换成指针。
char *arr[]={"hello"} 同样的初始化char *[]数组,"hello"字符数组转换成了首元素指针,也就是相当于 char *arr[]={ &"hello"[0] }