数组,指针,指针数组,数组指针

指针

指针是在32位系统下占四个字节,64位系统下占八个字节的一种类型,指针指向的内容可以是常量,变量,函数,结构体,指针本身,数组,等等.
一级指针
一级指针常常在函数传参时使用,可传的参数有一维数组,常量指针,函数指针等等都可以
但我们要注意不要在函数中,通过改变形参的指向来达到改变实参指向的效果,因为形参和实参只是两个指向同一空间的不同的指针.但因为形参和实参指向的是同一空间,所以可以在形参中改变其指向空间的值,如此实参指向的空间地址也发生改变。
二级指针
二级指针可以用于传递指针数组 char *arr[3]={"aaaaa","bbbbb","ccccc"};
这种用法可以通过二级指针进行传参
void PrintfStr(char **arr);

数组与指针的转换

数组名在进行加减法,函数传参时会隐式退化为指针,这个指针指向数组的第一个元素,但数组名隐士退化的指针是常量指针,不能赋值.

和指针的区别:指针本身也是一个变量,在内存中有自己的空间,来存放所指向内容的地址。所以指针可以为左值,数组名不可以

指针数组

指针数组是数组 它的定义方式为int*arr[],也就是一个数组中存放的每个元素是指针,(实则不放指针也行), int *arr[]相当于int **arr.

数组指针

数组指针是指针,它的定义方式为 int(*arr)[],它也称为行指针,我们通常赋值方式为
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int (*p)[10] = &arr; 数组指针加1跳过的是整个数组,数组指针解地址是数组首元素地址

易错点以及面试题

代码 char* pstr = "hello bit.";
特别容易让同学以为是把字符串 hello bit 放到字符指针 pstr 里了,但 是/本质是把字符串 hello bit. 首字符的地址放到了pstr中
#include <stdio.h>
int main()
{
   char str1[] = "hello ";
   char str2[] = "hello .";
   char *str3 = "hello .";
   char *str4 = "hello .";
   if(str1 ==str2)
printf("str1 and str2 are same\n");
   else
printf("str1 and str2 are not same\n");
     
   if(str3 ==str3)
printf("str3 and str4 are same\n");
   else
printf("str3 and str4 are not same\n");
     
   return 0;
}

这里最终结果是

str1 and str2 are not same

str3 and str4 are same\n
这里str3和str4指向的是一个同一个常量字符串。

C/C++会把常量字符串存储到单独的一个内存区域,当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。
但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同。
学了指针数组和数组指针我们来一起回顾并看看下面代码的意思

int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];

int arr[5];int型的一维数组
int *parr1[10];int型的数组指针
int (*parr2)[10];int型的指针数组
*int (parr3[10])[5];int型的数组指针数组
数组指针解地址是首元素地址指针
在这里插入图片描述
在这里插入图片描述

一维数组传参方式

void test(int arr[])
{}
void test(int arr[10])//
{}
void test(int *arr)//
{}
void test2(int *arr[20])//
{}
void test2(int **arr)//
{}
int main()
{
 int arr[10] = {0};
 int *arr2[20] = {0};
 test(arr);
 test2(arr2);
}

二维数组传参方式

void test(int arr[3][5])//ok?
{}
void test(int arr[][5])//ok?
{}
void test(int (*arr)[5])//ok?
{}

//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
//这样才方便运算

一维数组
在一维数组中,数组名(必须是数组名,不加方括号的)在进行在进行+ - 函数传参操作中隐式转化为指针
同理指针在进行【】后亦可以转化为数组(自己发现的)
书上理解是下标引用和间接访问是对等的,这也解释了为什要去掉方括号进行计算,因为去掉【】就由下标引用转化为间接访问了,而间接访问是由指针操作完成。
惊人的结果:

int a[3]={1,2,3};
printf("%d",2[a]);
return 0;
这里的2【a】竟然是合法的,这是因为下标引用和间接访问是等价的,下面是转化规则
下标引用和间接访问的转化规则:括号外【括号内】=(括号外+括号内)
因此合法是因为2【a】=
(2+a),a是数组进行加减法时会隐式转化为指针。
int a

猜你喜欢

转载自blog.csdn.net/qq_41016462/article/details/88090882