C语言指针

197 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

C语言指针

(一)各种指针的定义

1.一个整型数 : int a;

2.一个指向整型数的指针: int *a;

3.一个指向指针的指针,它指向的指针指向一个整型数: int **a;

4.一个有10个整型数的数组:int a[10];

5.一个有10个指针的数组,每个指针指向一个整型数:int *a[10];

6.一个指向有10个整形数的数组的指针:int (*a)[10];

7.一个指向指针的指针,被指向的指针指向一个有10个整型数的数组:int (**a)[10];

8.一个指向数组的指针,该数组有10个整形指针:int *( *a)[10];

9.一个指向函数的指针,该函数有一个整形参数并返回一个整形数:int (*a)(int);

10.一个有10个指针的数组,每个指针指向一个函数,该函数有一个整形参数并返回一个整形数:int (*a[10])(int );

11.一个函数的指针,指向的函数的类型是有两个整形参数并且返回一个函数指针的函数,返回的函数指针指向有一个整形参数且返回整形数的函数:int (* ( *a)(int,int))(int);

(二)各种指针的介绍

1.int a;

a 是一个变量,指向内存的一个空间地址,通过&a得到该地址空间,通过a可以取到该地址空间中的值。

2.int *a;

定义了一个指向整形数的指针a,a是一个返回值是整型数的指针。有一个变量int x;a=&x;a便指向了x的地址空间,通过*a可以取出地址空间中的数据,值和x是一致的。

通过代码来深入理解一下

#include<stdio.h>

int main()
{
        int a = 10;
        int *p = &a;
        printf("变量名访问a:%d\n",a);
        printf("a的地址是:%p\n",&a);
        printf("地址访问a:%d\n",*(&a));
        printf("指针访问a的地址是%p\n",p);
        printf("指针变量访问a:%d\n",*p);
        return 0;
}

运行结果如下:

image.png

3.int **a;

定义了一个二级指针a,返回值是整型的指针,有变量int y;int *b=&y; int **a=&b;

b指向y的地址,a指向b的地址,b中存放的是y的地址,a中存放的是b的地址,通过*a可以得到b的地址,由于是二级指针,**a便取到了y的值。

代码示例

#include<stdio.h>

int main()
{
        int a = 10;
        int *p = &a;
        int **pp = &p;
        printf("通过变量名访问a:%d\n",a);
        printf("通过地址访问a:%d\n",*(&a));
        printf("通过一级指针p访问a:%d\n",*p);
        printf("二级指针pp访问a:%d\n",*(*pp));
        printf("a的地址为:%p\n",&a);
        printf("一级指针:a的地址%p\n",p);
        printf("p的地址为:%p\n",&p);
        printf("二级指针pp访问打印p的地址:%p\n",pp);
        return 0;
}
~  

运行结果

image.png

4.int a[10];

定义了一个整型数的数组,大小为10,有10个元素。可以通过数组名加下角标进行访问数组的数据,下角标为0-9,其他的为数组越界。

代码示例

#include<stdio.h>

int main()
{
        int a[10] ={1,2,3,4,5,6,7,8,9,10};
        int size = sizeof(a)/sizeof(a[0]);
        for(int i=0;i<size;i++){
                printf("%d ",a[i]);
        }
        putchar('\n');

        return 0;
}

运行结果

image.png

5.int *a[3];

定义了一个指针数组,数组中的每一个元素都是指针,指向内存的某一个空间地址。

如:有三个变量int x,y,z;int *a[3]={&x,&y,&z};

分别将三个指针指向x,y,z的地址空间。

代码示例:

#include<stdio.h>

int main()
{
        int a = 10;
        int b = 20;
        int c = 40;
        int *arr[3] = {&a,&b,&c};
        for(int i=0;i<3;i++){
                printf("%d ",*arr[i]);
        }
        putchar('\n');
        return 0;
}

运行结果

image.png

6.int (*a)[3];

数组指针,定义一个指针,指向一个数组。

数组指针才是真正等同于二维数组名。

代码示例

#include<stdio.h>

int main()
{
        int arr[3][4] = {{11,22,33,44},{12,13,14,15},{13,45,67,88}};
        int (*a)[4];
        a = arr;
        for(int i=0;i<3;i++){
                for(int j=0;j<4;j++){
                        printf("%d ",*(*(a+i)+j));
                }
                putchar('\n');

        }
        putchar('\n');
        return 0;
}

运行结果

image.png

void (*p)();

返回值为void 的无参数的函数指针

示例

#include<stdio.h>

void Print()
{
        puts("程序启动,欢迎使用!");
}
int main()
{
        void (*p)();
        p = Print;
        (*p)();

        return 0;
}

运行结果:

image.png

int (*p2)(int );

返回值为int类型,形式参数为一个int类型的函数指针

代码

#include<stdio.h>

void Print()
{
        puts("程序启动,欢迎使用!");
}
int GetData(int data)
{
        printf("%d\n",data);
}

int main()
{
        void (*p)();
        int (*p2)(int);
        p2 = GetData;
        p = Print;
        (*p)();
        (*p2)(10);
        return 0;
}

运行结果

image.png

7.int(**a)[2];

相当于一个二级指针,它存放的是一个指针的地址,这个指针指向有2个元素的数组。

代码示例

#include<stdio.h>

int main()
{
        int arr[2][2]={{1,2},{3,4}};
        int (*p2)[2] = arr;
        //int **a = &p2;
        int (**a)[2] = &p2;
        for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                        printf("%d ",arr[i][j]);
                }
                printf("\n");
        }
        printf("\n");
        //printf("%d\n",arr[0][0]);
        for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                        printf("%d ",*(*(p2+i)+j));
                }
                printf("\n");
        }
        printf("\n");

        for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                        printf("%d ",*(*(*a+i)+j));
                }
                printf("\n");
        }
        putchar('\n');
        return 0;
}

运行结果

image.png

8.int*( *a)[2];

相当于一个二级指针,存放是一个数组的地址,数组中有2个整型数的指针。

9.int *a(int);

这是一个函数指针,指向某个函数的地址空间。该函数有以一个整形参数。

10.int (*a[3])(int );

这是一个数组,数组中存放的是3个指针,每一个指针指向一个函数。也就是函数指针的数组。

代码

#include<stdio.h>int GetMax(int a,int b){        return a>b?a:b;}int GetMin(int a,int b){        return a<b?a:b;}int GetSum(int a,int b){        return a+b;}int main(){        int a = 10;        int b = 20;        int ret;        int (*p[3])(int,int) = {GetMax,GetMin,GetSum};        for(int i=0;i<3;i++){                ret = (*p[i])(a,b);                printf("ret = %d\n",ret);        }        return 0;}

运行结果

image.png

11.int (* ( *a)(int,int))(int);

这是一个函数指针,其指向的函数是带有两个形参的函数,并且返回值为函数指针,返回的函数指针是带一个形参,并且返回值为整型,也就是返回的函数指针指向带一个形参并且返回值为int 的函数。