0


指针进阶的深度剖析

一.文章目录

1.字符指针

2.指针数组

3.数组指针

    3.1数组指针的定义

     3.2&数组名vs数组名

     3.3  数组指针的使用

4.数组传叁和指针传叁

 4.1一维数组传叁

4.2 二维数组传叁

4.3 一级指针传叁

4.4  二级指针传叁

5.函数指针

6.函数指针数组

7.指向函数指针数组的指针

二.

    1.字符指针      

字符指针的定义:字符指针是指指向字符的指针,其指针类型为char*,如char a='w'    char*b=&a, *b='h',对b解引用a='h'

那么字符指针变量可以存放地址,可不可以存放字符串吗?

char*c="abcde"

printf("%s",c);

我们来打印一下结果来看一下

那么指针变量c里存放的到底是不是abcdef这个字符串呢?答案肯定是否定的,我们可以来想一下c占4个字节,abcde\0一共6个字节,显然是放不开的,其实指针变量c里存放的是首元素a的地址,而对于printf这个函数而言,只要你给我首元素的地址,我就能把这个字符串给打印出来。

大家一起来看一个题。

#include<stdio.h>

int main()

{

char*c="abcdef";

char*b="abcdef";

char arr1[7]="abcdef";

char arr2[7]="abcdef";

if(c==b)

{

printf("c=b");

}

else

{

printf("c!=b");

}

if(arr1==arr2)

{

printf("arr1=arr2");

}

else

{

printf("arr1!=arr2");

}

return 0;

}

我们来看一下程序运行结果

我们可以看到c=b,而arr!=arr2,那么为什么会是这样一种结果呢?在这里c和b指向的是一个同一个常量字符串,c/c++会把常量字符串存储到单独的一个内存区域,当几个指针,指向同一个字符串时,他们实际会指向同一块内存,但是用相同的常量字符串去初始化不同的数组就会开辟出不同的内存快,所以c=b,arr1和arr2不同。

     c和b

abcdef\0
arr1
abcedef\0
arr2
abcdef\0
二.指针数组

指针数组是指存放指针的数组,其形式为intarr[],chararr[],那么它在实际中有什么应用呢?我们不妨来看一下。

#include<stdio.h>

int main()

{

int arr1[]={1,2,5,4};

int arr2[]={5,6,7,8};

int arr3[]={9,10,11,12}

int*arr4[]={arr1,arr2,arr3};

int i=0;

for(i=0;i<3;i++)

{

printf("%d",arr4[i][j]);也可以写成printf("%d",*(arr4[i]+j))

}

return 0;

}

三.数组指针

数组指针是指存放数组地址的指针,其类型为int(p)[],char a='w';charb=&a;这里的b是字符指针,int a=3,int b=&a,这里的b是整形指针,int arr[5]={1,2,3,4,5};int(b)=&arr这里的b就是数组指针,b指向一个数组,该数组有5个元素,每个元素是int类型

我们再来看一下&数组名和数组名的区别:假设一个数组的数组名为arr,arr通常情况下就是数组首元素的地址,而&arr则是整个数组的地址,我们打印一下看一下,

通过打印我们可以看到arr确实和首元素地址一样,但&arr和arr在数值上也是一样的 ,这又是为什么呢?因为它们都是从第一个元素开始指向的,但是如果我们给他们的地址分别+1,32平台上我们会发现会跳过四个字节,而对&arr+1会跳过整组数据,也就是跳过16个字节。我们来看一下

那么数组指针在实际中的作用又是什么呢?我们来看一个例子

通过这个例子我们可以发现,数组指针我们主要是用来处理二维数组

由此我们可以看到数组指针主要是针对二维数组的。

四.数组传叁和指针传叁

1.一维数组传叁

int main()

{

void test(int arr[])

void test(int arr[10])

void test(int*arr);

void test(int *arr2[20])

void test(int**arr2)

int arr[10]={0};

int*arr2[20]={0};

test(arr);

test(arr2)

2.二维数组传叁

void pul(int arr[][3]);

void pul(int arr[2][3])

void pul(int (*p)[3]);

int arr[2][3]={1,2,3,4,5,6};

pul(a);

3.一级指针传叁

void pul(int*c)

int a=3;

int*p=&a;

pul(p);

pul(&a)

pul(arr)

4.二级指针传叁

void pul(int**c);

int *p=&a;

int**g=&p

int*arr[10]

pul(&p)

pul(g)

pul(arr)

五.函数指针

函数指针的定义:函数指针是指存放函数地址的指针,其类型为 int(*P)(int ,int),*p解引用和p都表示调用函数,因为p中存放的是函数的地址,举个例子大家可以一起来看一下,

int add(int x,int y)

{

return x+y;

}

#include<stdio.h>

int main()

{

int x=0;

int y=0;

int (*p)(int,int)=add ;// add和&add都表示函数地址

int ret=(p)(3,4) ; //*这里的p也可以写成p因为p里存放的是add的地址,对*p解引用这种操作是为了更好地理解,对其解引用找到对应的函数*

printf("%d”,ret);

return 0;

}

我们来看一下打印的结果

通过函数指针我们将函数地址保存了起来,通过对函数指针变量或直接运用函数指针变量,我们可以达到调用函数的效果。大家可以在看一个例子

计算机功能的实现

#include<stdio.h>

int add(int x,int y)

{

return x+y;

}

int sub(int x,int y)

{

return x-y;

}

int mul(int x,int y)

{

retutrn x*y

}

int div(int x,int y)

{

return x/y;

}

void cal(int(*p)(int,int))

{

  int x=0;

 int y=0;

scanf("%d%d",&x,&y);

int ret=(*p)(x,y);

printf("%d",ret);

}

void menu()

{

printf("0.退出.1.add2.sub.3.mul4.div);

}

int main()

{

int input=0;

do

{

menu();

scanf("%d",&input);

switch(input)

{

case 0:

printf("请退出);

case 1:

cal(add);

case 2:

cal(sub);

case 3:

cal(mul);

case 4:

cal(div)

}while(input)

return 0;

}

通过这样一种方式,我们可以将加减乘除函数的地址通过给函数传叁用函数指针来接受的方式,在一个函数里实现,既方便又快捷。我们一起来运行一下看一下结果

六.函数指针数组

函数指针数组是存放函数指针的数组,其类型为int(*arr[4])(int ,int)={add,sub,mul,div)

我们来看一下它的一个实际的应用:

我们通过将函数的地址保存在一个函数指针数组里面的方式,从而更好地可以调用多个函数

七.指向函数指针数组的指针

int (*arr[5])(int,int)={0,add,sub,mul,div);

int (*(*arr)[5])(int x,int y)=&arr,

我们可以这样理解 首先它是个指针(arr)指向的是数组 [],数组中每个元素的类型是函数指针,也就是 int ()(int,int)

标签: python 开发语言

本文转载自: https://blog.csdn.net/m0_70386582/article/details/125173965
版权归原作者 m0_70386582 所有, 如有侵权,请联系我们删除。

“指针进阶的深度剖析”的评论:

还没有评论