1.字符指针是一个指针变量,存放字符的地址

const char*p="abcdef"不是把abcdef的给了p,只是把a的地址赋给p(这个是常量字符串,不能通过*p改变字符串)

//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[] = "abcdef";
//	const char* p1 = "abcdef";
//	const char* p2 = "abcdef";
//	/*char* p1 = arr1;
//	char* p2 = arr2;*/
//	if (p1 == p2)
//	{
//		printf("hh\n");
//	}
//	else
//		printf("aa\n");
//	printf("%s", arr1);
//	return 0;
//}

这里arr1和arr2是两个数组所以它们的地址不一样,因为常量字符串是不能改变的,不能*p改变字符串,p1,p2存的地址是一样的,所以p1==p2

2.指针数组,其实是数组,数组里面存放指针int*arr[]存放整型指针类型的数组,其他同理。

{
//	int arr1[] = {1,2,3,4,5 };
//	int arr2[] = {2,3,4,5,6 };
//	int arr3[] = {3,4,5,6,7};
//	int arr4[] = {4,5,6,7,8 };
//	int* arr[] = { arr1,arr2,arr3,arr4 };
//	int i;
//	for (i = 0 ; i < 4; i++)
//	{
//		int j;
//		for (j = 0; j < 5; j++)
//		{
//			printf("%d ", *(arr[i] + j));
//		}
//		printf("\n");
//	}
//	return 0;
//}

指针数组里面存放指针,数组名不就是数组第一个元素的地址,通过解引用找到指针所指向数组,在经过指针加减运算,找到对应下标元素,打印。


3.数组指针,其实是指针,指向数组的指针,存放数组的地址,可以把一个数组的地址直接交给数组指针

数组名是首元素的地址,arr[0]也是首元素地址,&arr是整个数组的地址。 

int*p[10]表示的是整型指针数组,里面是指针([]的优先级要高于*),所以数组指针应该是int(*p)[10]

char*arr[5]表示存放五个指针的数组(指针数组)

char*(*pa)[5]表示指针存放5个数组指针类型的元素,pa指向5个元素的数组,里面元素是char*类型的

 int arr[5]                 //arr是一个五个元素的整型数组

int *parr1[10]          //parr1是一个数组,里面有十个元素,每个元素的类型是int*,parr1是指针数组

int(*parr2)[10]         //parr2是一个指针,该指针指向了一个数组,数组里面有十个元素每个元素的类型是整型,parr2是数组指针

int(*parr3[10])[5]     //parr3是一个数组[]的结合性大于*,该数组有十个元素,每个元素是一个数组指针

                                   指针指向的每个数组 里面有5个元素,每个元素都是int型。  

//int main()
//{
//	int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
//	print1(arr, 3, 5);
//	print2(arr, 3, 5);
//	return 0;
//}
//void print1(int arr[3][5], int x, int y)
//{
//	int i, j;
//	for (i = 0; i < x; i++)
//	{
//		for (j = 0; j < y; j++)
//		{
//			printf("%d ", arr[i][j]);
//		}
//		printf("\n");
//	}
//}
//void print2(int(*p)[5], int x, int y)
//{
//	int i, j;
//	for ( i = 0; i < x; i++)
//	{
//		for (j = 0; j < y; j++)
//		{
//			printf("%d ", *(*(p+i) + j));//p表示第一行五个元素数组的地址,p+i表示第i行的地址,*(p+i)+j表示i行j列
//			printf("%d ", (*(p+i))[j]);
//			}
//		printf("\n");
//	}
//}

int arr[3][5]={0}; 

A.二维数组调用用数组接收时,void test(int arr[3][5])列的元素个数不可以省略,print1就是数组接收打印

B. 二维数组用指针接收时,二维数组数组名是第一行元素的地址,void test(int (*arr)[5]),print2就是一个数组指针来接收,表示第一行数组的地址,在加j就是一行j列。

思考,如果指针定义部分形参是一个指针,调用部分形参可以写变量的地址,还可以写一级指针,

二级指针传参,一级指针取地址,二级指针传参都可以用二级指针形参来接收

 如果调用传的是指针数组,可以用二级指针来接收。

//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int i = 0;
//	int* p = arr;
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", p[i]);
//		printf("%d ", arr[i]);//数组名下标,数组名=首元素地址=p指针
//		printf("%d ", *(arr+i));
//		printf("%d ", *(p+i));//地址加减运算找下标
////arr[i]=p[i]=*(arr+i)=*(p+i)
//	}
//	return 0;
 }

int arr[10]={0},把数组名作为实参传给函数时,如test(arr)函数调用,函数定义部分可以写成

数值形式void test(int arr[]),void test(int arr[10])拿一个整型数组来接收是可以的,元素可以不写

void test(int*arr)拿一个整型指针来接收也可以


int *arr[20]={0};这是一个指针数组,test2(arr2)函数调用时,用一个数组接收可以,如void test2(int*arr2[20])元素个数可以不写

用指针接收时,void test(int **arr2)表示一个指针的地址二级指针,二级指针是一级指针的地址