> 文章列表 > 【C语言】与指针相关的五个概念

【C语言】与指针相关的五个概念

【C语言】与指针相关的五个概念

作者:指针不指南吗
专栏:C语言

🐾或许会很慢,但是不可以停下🐾

文章目录

  • 前言
  • 1.指针数组
  • 2.数组指针
  • 3.指针函数
  • 4.函数指针
  • 5.函数指针数组

前言

指针数组、数组指针、指针函数、函数指针、函数指针数组的区别,五个概念最本质的区别在后面,从后往前去理解比较好区分和认识。

    指针数组是一个数组,装着指针的数组。数组指针是一个指针,指向数组的指针。指针函数是一个函数,函数的返回值是指针。函数指针是一个指针,指向函数的指针。函数指针数组是一个数组,装着函数指针的数组。

1.指针数组

是什么?是一个数组,数组存放的是指针。

//定义了一个指针变量,将字符串赋给指针变量,其实赋的是第一个字符的地址,这时的字符串被称为常量字符串,不可通过指针修改该常量的值。
char *p1 = "zzzzz";  
char *p2 = "xxxxx";
char *p3 = "ccccc";//定义了一个指针数组,将三个指针变量赋值给这个数组的三个元素
char *arr[3] = {p1,p2,p3};  也就是:arr[0] == p1arr[1] == p2arr[2] == p3也等价于:
char *arr[3] = {"zzzzz","xxxxx","ccccc"};
//arr是一个四个元素的数组,每个元素都是一个char *类型的指针,这些指针都指向常量字符串的首地址

指针数组比较适用于指向若干个字符串,使字符串的处理更加灵活。

2.数组指针

是什么?是一个指针,指向数组的指针。

数组指针和指针数组的区别

int * a[5] 和 int (*a)[5]

可以看出的是,他们只相差一个括号,由于存在优先级的关系(( ) > [ ] >* ),如果不加括号,a会先与[ ]结合,加了括号,a则先与*结合。加括号为的是改变运算的结合顺序。

int * a[5]没有括号,a先与[ ]结合,是个数组;

int (*a)[5]加了括号,a先和 * 结合,是个指针。

故:

int * a[5]是指针数组,本质上是一个数组,数组里存放的元素是指针,指针的类型是int *型,指向一个整型数。

int (*a)[5]是数组指针,本质上是一个指针,指针所指对象是一个数组,数组的类型是int [5]型。


1、数组指针和一维数组

int a[5]={1,2,3,4,5};
int (*p)[5]=NULL;
p=&a;

2、数组指针与二维数组

int a[ 2 ] [3]={1,2,3,4,5,6};
int ( * p)[3]=NULL;
p=a;

值得注意的是,int (*p)[3]中的3,此处应该写上的是二维数组的列数,亦或者是每个一维数组的元素个数。

另外,通过比较一维数组和二维数组给p赋值,不难发现,两者有差别,因为二维数组的数组名a的类型就是int (*)[N],类型相同,所以可以直接赋值。

int i,j;
for(i=0;i<2;i++)
{for(j=0;j<3;j++){printf("%d ",*(*(p+i)+j));//遍历输出}
}

对于*(*(p+i)+j) ,一个通俗的理解,里层 * 是为了先选定数组,取数组,然后外层 * 再对数组中的元素取值,i,j分别是两次取值的偏移量。我们说对数组指针对二维数组才有意义,其意义主要体现在里层的p+i上,可以通过移动p,访问连续的不同一维数组。

3.指针函数

是什么?是一个函数,函数的返回值是指针。

//定义了一个指针函数
//这个函数的返回值的类型是char*型,也就是返回的是一个指针,这个函数叫fun,有两个char*类型的参数。
char* fun(char* a,char* b)
{语句块;
}

简单举个例子吧

//自定义一个mystrcpy指针函数
char* mystrcpy(char* dest,char* src)
{char* temp = dest;while(*src != '\\0'){*dest++ = *src++;}*dest = '\\0';return temp;
}
int main()
{char str[10] = {0};char* p = "hello";mystrcpy(str,p);printf("%s\\n",str);return 0;
}

用一个字符串操作函数strcpy来举例子,在这里自定义了一个指针函数,函数有两个参数,两个参数都是char*类型的指针,函数体的内容,先定义了一个指针保存了参数传入的地址,通过循环,把后面的指针指向的内容赋值给前面指针的指向,从而实现了字符串copy操作,最终返回之前保存的那个地址,也就是返回值是指针的函数,即指针函数。

指针函数常用于返回数组,字符串等数据结构指针等,最典型的就是字符串操作函数如strcpy,strcat,strstr看到函数原型。

4.函数指针

是什么?是一个指针,指向函数的指针。

当一个函数指针指向一个函数,就可以通过这个指针来调用函数。

#include <stdio.h>
int Max(int, int);  //函数声明
int main()
{int(*p)(int, int);  //定义一个函数指针int a, b, c;p = Max;  //把函数Max赋给指针变量p, 使p指向Max函数printf("please enter a and b:");scanf("%d%d", &a, &b);c = (*p)(a, b);  //通过函数指针调用Max函数printf("a = %d\\nb = %d\\nmax = %d\\n", a, b, c);return 0;
}
int Max(int x, int y)  //定义Max函数
{int z;if (x > y){z = x;}else{z = y;}return z;
}

5.函数指针数组

是什么?是一个数组,数组存放的是函数指针。

int (*parr1[10])(int, int);
//含有10个元素的数组,每个元素为函数指针
//且函数指针指向的函数参数为int、int,返回值为int。double (*parr2[5])(int, char);
//含有5个元素的数组,每个元素为函数指针
//且函数指针指向的函数参数为int、char,返回值为double。

应用: 将加减乘除分别封装成四个函数,在main函数中调用。

int ADD(int x, int y)
{return x + y;
}
int SUB(int x, int y)
{return x - y;
}
int MUL(int x, int y)
{return x * y;
}
int DIV(int x, int y)
{return x / y;
}
int main()
{int x, y, input, ret;int(*pfArr[])(int, int) = { 0, ADD,SUB, MUL, DIV };//0只是为了下面调用函数是方便,不放也可以//函数指针数组,内部的四个函数指针指向的函数类型相同,//参数为int、int,返回值为int。do{printf("0.退出\\n1.加\\n2.减\\n3.乘\\n4.除\\n");scanf("%d", &input);if (0 == input){printf("退出\\n");}else if (input >= 1 && input <= 4){printf("请输入两个数");scanf("%d%d", &x, &y);printf("%d\\n", (pfArr[input](x, y)));//如(pfArr[1](1, 2))就是调用数组下标为1的元素,//在这里是调用ADD函数,并用1和2进行运算//即对1和2进行加法运算}else{printf("输入错误,重新输入\\n");}} while (input);
}

部分解释及代码转载网络,侵删
Alt