1. 字符指针
1.字符指针与字符数组
字符指针一共有两种使用方法
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
//1.
char ch = 'a';
char* p = &ch;
*p = 'w';
//2.
const char* ptr = "abcdef";
printf("%s\n", ptr);
return 0;
}
第一种就是非常常规的指针用法;而第二种本质上把字符串的首字母地址放在了ptr中。
字符数组我们都很熟悉形式就如同下面
char str[] = "abcdef";
为了加快我们的理解有下面这类题目
这里12的区别在于他们分别创立的两个地址存放相同的字符串,所以他们的起始地址是不一样的,而34中的字符串为常量字符串34用的是同一个所以他们起始地址指向的是同一个位置,所以3和4是相同的。
2.指针数组
1.概念
我们在理解指针数组的时候可以采用类比的方法。
整形数组(int arr[10])——存放整形元素的集合。
字符数组(char str[10])——存放字符元素的集合;所以指针数组就是存放指针的集合书写方式为*int arr[10]
接下来我们用指针数组来模拟实现二维数组
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 6,7,8,9,10 };
int arr3[] = { 11,12,13,14,15 };
int *arr[3] = { arr1,arr2,arr3 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
int arr[3] = { arr1,arr2,arr3 };我们重点分析一下这一步,数组内存放的都是数组的名字(首元素的地址),所以arr的类型就为int;
3.数组指针
1.概念
同样我们理解数组指针也是类比:整形指针(intp)——指向整形的指针,存放整型变量的地址的指针变量。
字符指针(charp)——指向字符的指针,存放字符变量的地址的指针变量;所以数组指针就是**
指向数组的指针,存放数组的地址的指针变量**。
这里[]的优先级别很高,第一个p1先和[]结合就是数组,然后类型为int*;而第二个就是先是指针类型就是int[10],这个就是数组的类型;所以数组指针的写法就是int(*p2)[10].为了搞清楚数组指针的用法我们先讲一讲&数组名和数组名的关系。
2.&数组名VS数组名
这里我们就可以看出arr和arr[0]都是首元素的地址,而&arr中表示的就是整个数组的地址但是起始的时候用的还是首元素的地址,但是&arr+1之后整个数值是加了40也就是一整个数组的大小。(&arr表示的是数组的地址)。我们打开监视窗口可以看到&arr的类型为
int(*)[10];是一种数组指针的类型。 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int (*p)[10]= &arr;//把arr的地址赋值给指针变量p
但是我们在使用中很少对一维数组这样使用数组指针。数组指针一般用于二维数组
我们先分析一下二维数组的数组名表示什么,
```c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void print(int(*p)[5], int r, int c)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", p[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};
print(arr, 3, 5);
return 0;
}
这里arr既然表示的是数组的地址所以传参的时候就可以用数组指针。
4.数组传参和指针传参
1.数组传参
1.一维数组传参
//一维数组传参,参数部分可以是数组也可以是指针
void text1(int arr[],int sz)
{
;
}
void text2(int* p, int sz)
{
;
}
int arr[10] = { 0 };
text1(arr,10);
text2(arr,10);
2.二维数组传参
二维数组传参,参数部分可以是数组也可以是指针。
//二维数组传参
void text1(int arr[][], int r,int c)
{
;
}
void text1(int (*p)[5], int r, int c)
{
;
}
int arr[3][5] = {0};
text1(arr, 3,5);
text1(arr, 3, 5);
2.指针传参
1.一级指针
当一个函数的参数部分为一级指针的时候,函数可以接受的参数为指针。
2.二级指针
#include <stdio.h>
void test(int** ptr)
{
`printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
int *arr[5];
test(pp);
test(&p);
test(arr);
return 0;
}
二级指针接受的是一级指针的地址,所以塔可以接受pp(二级指针),&p就是一级指针的地址,这里的arr为指针数组,arr存放的是指针,而数组名表示的是地址,即是一级指针的地址。
5.函数指针
1.概念
类比数组指针——存放数组地址的指针变量
函数指针-存放函数地址的指针变量写法也和数组指针相类似
void test(int x, int y)
{
return x + y;
}
void(*p)(int, int) = &test;
这里写函数指针完全可以用数组指针的写法完全套用过来。