指针定义:
指针就是地址,口语中说的指针通常是指针变量(用来存放地址的变量)。
#include<stdio.h>
int main()
{
int a = 8;
int* p = &a;/*这里我们把a的地址用指针p来接收,p是一个指针变量。*/
return 0;
}
对于32/64位的机器来说,一个指针的大小是4/8个字节。
1字符指针
2数组指针
3指针数组
4数组传参和指针传参
5函数指针
6函数指针数组
7指向函数指针数组的指针
1.字符指针
列如:char*字符指针
#include<stdio.h>
int main()
{
char* p = "haha";
printf("%s ", p);
return 0;
}
上面意思是:把一个常量字符的首字符h的地址放在指针变量p中.。
#include<stdio.h>
int main()
{
char str1[] = "b";
char str2[] = "b";
char* str3 = "b";
char* str4 = "b";
if (str1 == str2)
{
printf("haha\n");
}
if (str3 == str4)
{
printf("hehe\n");
}
}
这里str1和str2是开辟两个不同空间,但用指针是指向第一个首字母的地址,所以是一样的。
2.指针数组
指针数组就是一个存放指针的数组。
int* arr[10];
char* arr[6];
#include<stdio.h>
int main()
{
int arr1[] = { 2,3,4,5,6 };
int arr2[] = { 3,4,5,6,7 };
int arr3[] = { 4,5,6,7,8 };
int* parr[] = { arr1,arr2,arr3 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d ", *(parr[i] + j));
}
printf("\n");
}
return 0;
}
3.数组指针
数组指针是一个指针,其表现形式为:int (*p)[];
3.1数组指针的使用
#include<stdio.h>
void print(int(*arr)[3], int x, int y)
{
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
print(arr, 3, 5);
//我们把这个二维数组,可以看成一维数组,
// *arr[3]就表示这个数组有三个元素,这三个元素指向的数组有五个元素
return 0;
}
同时让我们看一下这几段代码
int arr[8];/*一个有八个元素的整型数组*/
int* parr1[6];/*parr1是一个由6各元素的数组,每个元素类型是int*,是指针数组。*/
int(*parr2)[5];/*parr2是一个指针,指向一个数组,数组有5个元素,每个元素类型是是int.*/
int((*parr3)[10])[5]; /*parr1是一个由10各元素的数组,每个元素类型是int*,
是指针数组,该数组指针有5个元素,每个元素类型是int。*/
4.数组参数、指针参数
4.1一维数组的传参
着我们话不多说,直接看代码,通俗易懂:
#include<stdio.h>
void test1(int arr[])
void test1(int arr)
void test2(int* arr2)
void test2(int* arr2)
int main()
{
int arr1[20] = { 0 };
int* arr2[40] = { 0 };
test1(arr1); /*这里传参了一个整型数组,我们就用整型数组来接受。*/
test2(arr2); /*这里传参的数组类型是int*,我们就用int*接收。*/
return 0;
}
4.2二维数组的传参
代码来了:
#include<stdio.h>
void test(int arr[4][5]);
void test(int arr[][5]);
void test(int(*arr)[5]);
int main()
{
int arr[4][5] = { 0 };
test(arr);
return 0;
}
注:二维数组的传参,函数形参只能省略第一个数字,因为二维数组可以不知道多少行,但必须知道每行有多少元素。
4.3一级指针的传参
#include<stdio.h>
void print(int *p,int sz )
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));
}
}
int main()
{
int arr[5] = { 1,2,3,4,5 };
int *p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
print(p, sz);
return 0;
}
一级指针:就是把指针p传给函数。
4.4二级指针传参
5函数指针
函数指针就是一个指针指向的函数,列如:
void(*pf)(int,int) /*pf这个指针指向的是一个整形函数,返回是void*/
6.函数指针数组
把函数村到一个数组中,那么这个数组就叫函数指针数组。
void (*parr[])(int, int)
那么函数指针数组怎么用呢?我们可以用一个简单的计算器来看:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void menu()
{
printf("**1.add 2.sub **\n");
printf("**3.mul 4.div **\n");
printf("***** 0.exit ****\n");
}
void add(int x, int y)
{
return x + y;
}
void sub(int x, int y)
{
return x + y;
}
void mul(int x, int y)
{
return x + y;
}
void div(int x, int y)
{
return x + y;
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
int (*pfArr[5])(int, int) = {0,add,sub,mul,div};
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
if (input >= 1 && input <= 4)
{
printf("请输入这两个数:>");
scanf("%d%d", &x, &y);
int ret = pfArr[input](x, y);
printf("%d ", ret);
}
else if (input == 0)
{
printf("退出\n");
}
else
{
printf("小笨蛋输入错误\n");
}
} while (input);
return 0;
}
7.指向函数指针数组的指针
指向函数指针数组的指针是一个指针,指针指向一个数组,数组的元素都是函数指针。
#include<stdio.h>
void test(char* str)
{
printf("%s\n", str);
}
int main()
{
void (*p)(char*) = test;/* 函数指针p*/
void(*parr[])(char*) = test; /*函数指针数组parr*/
void (*((*pparr)[2]))(char*) = &parr; /*只想函数指针数组的指针pparr*/
}