笔记:指针作用4_操作指针和函数

指针+1/指针-1:把内存地址往后或者往前移动一个步长,步长和数据类型有关

二级指针定义:

int a=10;

int b=20;

int* p=&a;  //一级

int **p=&p;  //二级

数组指针:

         一维数组:

                

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

void swap(void* p1, void* p2, int len);

int main() 
{
    int a[] = { 1,2,3,4,5,6,7,8,9,10 };
    int len;

    len = sizeof(a) / sizeof(int);
    
    int* p = &a[0];

    for (int i = 0; i < len; i++)
    {
        printf("%d\n", *p++);//printf("%d\n", *p1);        p1++;
    }

/*循环解释:

        printf("%d\n", *p1)  //结果:1

        printf("%d\n", *(p1+1))  //结果:2

        printf("%d\n", *p1+1) //结果:2 ,仅是在1的基础上加1,而不是向下遍历

*/

}

        二维数组:

                情况一:分开定义

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() 
{
    int arr1[5] = { 1,2,3,4,5 };
    int arr2[5] = { 11,22,33,44,55 };
    int arr3[5] = { 111,222,333,444,555 };

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

    int** p = arr;//第一个*表示存放的是内存地址,第二个*表示指针的标志

/*

arr:表示数组首元素的地址(即 &arr[0]),类型是 int**(指向第一个 int* 元素的指针)。
&arr:表示整个数组的地址,类型是 int*(*)[3](指向 “包含 3 个 int * 元素的数组” 的指针),与 p 的类型(int**)不匹配。

*/

    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            printf("%d ", *(*p+j));
        }
        printf("\n");
        p++;
    }
}

                 情况二:合并定义

                        方法一:

int main() {
    int arr[3][3] = {{1, 2, 3},
                     {4, 5, 6},
                     {7, 8, 9}};
    int sum = 0;
    int i;
    int *p = &arr[0][0];  // 将二维数组转换为指向首元素的指针(int*类型)
    
    for (i = 0; i < 3; i++) {
       
        sum += *(p + i * 3 + i);   // 指针访问主对角线元素:第i行的对角线元素位置是 i*3 + i
    }
    printf("3×3数组主对角线元素的和为:%d\n", sum); // 结果为1+5+9=15
    return 0;
}

                        方法二:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() 
{
    int arr[3][5] =
    {
        {1,2,3,4,5},
        {11,22,33,44,55},
        {111,222,333,444,555}
    };

    int (*p)[5] = arr; //原型:int[5] *p=arr

    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            printf("%d ", *(*p+j));
        }
        printf("\n");
        p++;
    }
}

                两种定义方法得到的结果相同,但意义不同:

                int *p = &arr[0][0]; 

                        int * 是 “指向单个 int 元素的指针”,&arr[0][0] 是二维数组首元素的地址

                        (即 arr[0][0] 这个具体元素的地址)

                int (*p)[5] = arr;

                        int (*)[5] 是 “指向包含 5 个 int 元素的数组的指针”,也称 “行指针”。
                        arr 是二维数组名,在 C 语言中会隐式转换为指向首行的指针

                        (即指向 arr[0] 这一行的指针,arr[0] 是包含 5 个元素的一维数组)。

                行指针(int (*)[n])指向一整行数组,适配二维数组的 “行 - 列” 逻辑;
                元素指针(int *)指向单个元素,适配二维数组在内存中连续存储的特性。

                 情况三:每组数量不同的数组定义

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() 
{
    int arr1[3]={1,2,3};
    int arr2[6]={1,2,3,4,5,6};
    int arr3[9]={1,2,3,4,5,6,7,8,9};

    int len1 = sizeof(arr1) / sizeof(int);
    int len2 = sizeof(arr2) / sizeof(int);
    int len3 = sizeof(arr3) / sizeof(int);

    int len[3] = { len1,len2,len3 };  //

    int* arr[3] = { arr1,arr2,arr3 };  //存的是一维数组的内存地址,因此用int*
    
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < len[i]; j++)
        {
            printf("%d\t", arr[i][j]);
        }
        printf("\n");
    }
}

函数指针: 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

void method1();
int method2(int a, int b);
int main()
{
    void(*p1)()= method1;  //定义函数指针
    int(*p2)(int a, int b) = method2; 

/*定义的方法:

1.复制函数,如void method1(),int method2(int a, int b);

2.将函数名替换成指针(*p),得到:

        void (*p)()=函数名method1,int ()(int a, int b)=method2;*/

    /*调用第一个函数*/
    p1();//输出“模式1”

    printf("\n");

    /*调用第二个函数*/
    int x=p2(1, 2);  //定义一个数去接收返回值
    printf("%d\n", x);  //输出返回值
    return 0;
}

void method1()
{
    printf("模式1");
}

int method2(int a, int b)
{
    return a + b;
}

总结:

一维数组的情况:何时加 & ?
1.当用指针指向一维数组的首元素时:
int arr[5] = {1,2,3,4,5};
int* p = arr; // 正确(arr 是首元素地址,无需 &)
等价于 int* p = &arr[0]; // 也正确(&arr[0] 显式取首元素地址)
2.当用指针指向整个一维数组时(数组指针):
int (*p)[5] = &arr; // 必须加 &,因为 &arr 是整个数组的地址(类型为 int(*)[5])


二维数组的情况:何时加 & ?
1.当用行指针指向二维数组时:
int arr[3][5];
int (*p)[5] = arr; // 正确(arr 代表首行地址,无需 &)
2.当用元素指针指向二维数组的首元素时:
int* p = &arr[0][0]; // 必须加 &,因为 arr[0][0] 是普通元素(不是地址)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值