02. 指针和指针运算.md

173 阅读1分钟

1.多级指针

数据都是放在内存里面的,指针数据也是数据,也有自己的内存地址,内存地址 就是指针,所以指针也有自己的指针,即指针的指针。

#include <stdio.h>

int main() {
    int a = 100;
    int *p1 = &a;
    int **p2 = &p1;
    int ***p3 = &p2;
    printf("数据 是:%d",***p3);
    return 0;
}

2. 数组和数组指针

举例:

#include <stdio.h>

int main() {
    int a[] = {1, 2, 3, 4, 5};
    int index = 0;
    for (index; index < 5; ++index) {
        printf("data is %d\n", a[index]);
    }

    printf("a address=%p\n", a);
    printf("a get Address =%p\n", &a);
    printf("a  first element  address=%p\n", &a[0]);
    int *a_p = a;
    a_p ++;//指针地址向前移动,指向了下一个数据
    printf("element2 is %d\n", *a_p);
    a_p += 1;//移动指针
    printf("element3 is %d\n", *a_p);
    int *b = a_p;
    printf("element3 is %d\n", *b);
    b += 1000;//指针不会越界,这样获取系统中的随机值
    printf("element3 is %d\n", *b);

    return 0;
}


打印结果:

F:\dev\C\C0426\cmake-build-debug\C0426.exe
data is 1
data is 2
data is 3
data is 4
data is 5
a address=000000000061FDF0
a get Address =000000000061FDF0
a  first element  address=000000000061FDF0
element2 is 2
element3 is 3
element3 is 3
element3 is 690570822

Process finished with exit code 0

数组的内存地址 等于 数组的第一个元素的内存地址 等于 数组的&取地址符的取值

例子中a==&a

使用数组指针可以用来给数组赋值,遍历元素等操作,要注意数组元素的类型,以及其占用的内存位数。 如下:

#include <stdio.h>

int main() {

    int a[5] ;

    int index;
    int *a_p = &a;
    for ( index = 0; index < 5; ++index) {
        *(a_p + index) = index;
    }
    a_p = &a;
    for ( index = 0; index < sizeof a/sizeof (int); ++index) {
        printf("%d\n", *(a_p));
        a_p++;
    }

    return 0;
}


例子中 sizeof a/sizeof (int) =5 sizeof 是求占用字节数的函数。 输出:

F:\dev\C\C0426\cmake-build-debug\C0426.exe
0
1
2
3
4

Process finished with exit code 0

指针类型实际占用4个字节, int*、 float* 等多个类型的指针类型,便于便利取值,比如数组之中,根据指针类型便知道响应位置存储的是什么样的数据。 比如int 是4个字节,double 是8个字节,int* 取值便取后面的4个字节数据,double* 便取后面的8个数据。

3.函数 指针

函数指针实例:

#include <stdio.h>

void add(int num1, int num2) {
    printf("add result %d\n", (num1 + num2));
}

void operate(void(*method)(int, int), int num1, int num2) {
    method(num1, num2);//省略*号
    (*method)(num1, num2);//不省略* 号
    printf("%p\n", method);
}

int main() {

    void (*call)(int, int) =add;
    operate(call, 1, 2);
//    operate(add, 1, 2);
    printf("%p\n", add);
    printf("%p,%p", &add, add);
    return 0;
}


输出:

F:\dev\C\C0426\cmake-build-debug\C0426.exe
add result 3
00000000004017E0
00000000004017E0
00000000004017E0,00000000004017E0
Process finished with exit code 0

其中 void(*method)(int,int),int num1,int num2 声明函数指针的格式,函数指针的名称,返回值,参数值,后面的int num1,int num2 是实际执行方法的参数();

定义函数指针: 返回值(* 函数指针名称)(参数类型,参数类型,......)