您的位置:首页 > 教育 > 培训 > 北京有名的装修公司_源代码_静态网站模板_十大微商推广平台

北京有名的装修公司_源代码_静态网站模板_十大微商推广平台

2025/5/22 19:29:40 来源:https://blog.csdn.net/2301_77682837/article/details/143934059  浏览:    关键词:北京有名的装修公司_源代码_静态网站模板_十大微商推广平台
北京有名的装修公司_源代码_静态网站模板_十大微商推广平台

Day16

  • 指针变量的使用
    • 指针变量和字符串的关系
  • 指针进阶
    • 指针函数
    • 函数指针
    • 数组指针
    • 指针数组
    • 函数指针数组
    • 二级指针
    • 万能指针

在这里插入图片描述

指针变量的使用

指针变量和字符串的关系

  1. " hello world":字符类型的数组,本质是一个地址
    520:整形类型
    ‘A’:小数类型
    3.14:实数类型
  2. 字符串的本质是一个地址,可以使用一个指针变量存储该地址
    char *p = “hello world”;
  3. 字符串常量存储在静态区的只读区域,如果对上面这个指针 p修改的话将会出现段错误

指针进阶

指针函数

  1. 指针函数本质上是一个函数,返回值为指针的函数就是指针函数
  2. 指针函数调用的结果是一个左值
  3. 指针函数返回的必须是一个生命周期比较长的空间的地址,不能返回局部空间的地址
    • 全局变量的空间
    • 静态变量的空间
    • 堆区申请的空间
    • 主调函数以地址传入的空间
  4. 指针函数实现了将被调函数中的内存传递给主调函数使用
  5. 定义格式:返回值类型 *函数名(参数列表){函数体;return 地址;}
#include <stdio.h>//值返回函数
int fun_1(int n)
{n += 10;return n;
}//地址返回函数
int *fun_2()
{static int s = 66;return &s;
}int main(int argc, const char *argv[])
{int num = 520;//调用功能函数1int res = fun_1(num); //值返回函数,结果为右值,只读printf("res = %d\n", res);//  fun_1(num) = 1314; 	//值返回函数不能作为左值 	报错int *ptr = fun_2();printf("*ptr = %d\n", *ptr);*fun_2() = 777; 		//指针函数的返回值是一个左值return 0;
}

函数指针

  1. 函数指针本质上是一个指针,用于指向函数的入口地址的指针
    任何函数在被调用时系统都会为其分配运行空间,有空间就会有地址,有地址就可以用指针变量来指向他。存储函数运行空间地址的指针变量称为函数指针变量
  2. 任何一个函数的函数名都是该函数对应的入口地址,是一个地址常量
  3. 函数指针定义格式:返回值类型 (* 变量名)(参数列表);
  4. 函数指针变量的用法:和函数名用法一致
#include <stdio.h>int sum(int m, int n)
{return m+n;
}int judge(int m)
{return m%2 == 0 ? 1 : 0;
}void sort(int *arr, int n)
{for (int i = 1; i < n; i++){for (int j; j < n-i; j++){if (arr[j] > arr[j+1]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}printf("排序成功\n");
}int main(int argc, const char *argv[])
{//打印三个函数的地址printf("%p\t%p\t%p\t\n", sum, judge, sort);	//定义指针存储上面三个函数的入口地址int (*sum_ptr)(int,int) = sum;int (*judge_ptr)(int) = judge;void (*sort_ptr)(int *,int) = sort;//函数和函数指针都可以正常调用printf("和为: %d\n", sum(1,4));printf("和为: %d\n", sum_ptr(1,4));if (judge(56)){printf("是一个偶数\n");}else{printf("是一个奇数\n");}if (judge_ptr(56)){printf("是一个偶数\n");}else{printf("是一个奇数\n");}return 0;
}
  1. 使用函数指针完成函数回调(回调函数)
    函数回调:当调用某个函数时,不仅要向该函数中传递数据参数,也可以向该函数中传入一个功能
#include <stdio.h>int he(int m,int n)
{return m+n;
}int cha(int m, int n)
{return m-n;
}int ji(int m, int n)
{return m*n;
}//使用传入的函数指针调用别的函数
void calculate(int m, int n,int (*x)(int,int))
{int res = x(m,n);printf("结果为:%d\n", res);
}int main(int argc, const char *argv[])
{int num = 3, key = 6;calculate(num, key, he);calculate(num, key, cha);calculate(num, key, ji);return 0;
}

数组指针

  1. 数组指针的本质是一个指针,记录的是整个数组的地址
    数组指针针对的是整个数组,每偏移一个单位,内存地址就偏移了整个数组的大小
  2. 数组指针的定义格式:数据类型 (*指针名)[数组长度];
  3. 数组指针与一维数组的关系
    • 数组名是第一个元素的地址 ----> 变量的地址
    • 对一维数组名,再取地址,就得到了当前数组的地址(数组的地址)
#include<stdio.h>int main(int argc, const char *argv[])
{int arr[5] = {4,7,2,8,1};  	  //定义了一个长度为5的数组int *ptr = arr;     		  //普通元素的地址//定义一个指针变量,存储整个数组的地址int (*arr_ptr)[5] = NULL;  	 //定义一个数组指针arr_ptr = &arr;          	 //将数组指针指向整个数组    *arr_ptr = *&arrprintf("sizeof(arr) = %ld\n", sizeof(arr));    //20printf("ptr = %p,arr=%p, &arr[0]=%p, &arr = %p,arr_ptr=%p\n",\ptr, arr, &arr[0], &arr, arr_ptr);printf("ptr+1 = %p,arr+1=%p, &arr[0]+1=%p, &arr+1 = %p, arr_ptr+1=%p\n",\ptr+1, arr+1, &arr[0]+1, &arr+1, arr_ptr+1);//使用数组指针访问元素printf("数组元素分别是:");for(int i=0; i<5; i++){//printf("%d\t", (*arr_ptr)[i]);    // *arr_ptr ==> *(arr_ptr+0) ==> arr[0]printf("%d\t", arr_ptr[0][i]);    // *arr_ptr ==> *(arr_ptr+0) ==> arr[0]}return 0;
}
  1. 数组指针与二维数组的关系
    • 二维数组的数组名本质上是一个数组指针
    • 当数组指针与二维数组结合后,指针的偏移才有现实的意义
#include<stdio.h>int main(int argc, const char *argv[])
{int arr[2][3] = {{1,2,3}, {4,5,6}};    //定义一个二维整型数组//从元素的角度:定义了6个整形变量//从数组的角度:定义了两个一位数组//int *ptr = arr;        //?不可以进行  int *ptr=arr[0]int (*arr_ptr)[3] = arr;     //定义数组指针存储二维数组名printf("&arr[0][0]=%p, arr[0]=%p, arr=%p, arr_ptr=%p\n",\&arr[0][0], arr[0], arr, arr_ptr);printf("&arr[0][0]+1=%p, arr[0]+1=%p, arr+1=%p, arr_ptr+1=%p\n",\&arr[0][0]+1, arr[0]+1, arr+1, arr_ptr+1);//使用数组指针访问元素//arr_ptr 表示的是第一行的整体地址  //arr_ptr+i :表示任意一行的整体地址 //*(arr_ptr+i) :表示任意一行的第一个元素的地址  --> arr_ptr[i]//*(arr_ptr+i) +j :表示的是下标为i和j的元素的地址 --> arr_ptr[i]+j// *(*(arr_ptr+i)+j):表示任意一个元素   --> *(arr_ptr[i]+j)  -->arr_ptr[i][j]printf("数组元素分别是:\n");for(int i=0; i<2; i++){for(int j=0; j<3; j++){//printf("%d\t", arr_ptr[i][j]);printf("%d\t", *(*(arr_ptr+i)+j));}printf("\n");}return 0;
}

指针数组

  1. 指针数组本质上是一个数组,但是每个元素都是一个指针变量
  2. 定义格式:数据类型 *数组名 [数组长度]

函数指针数组

  1. 函数指针数组本质上是一个数组,数组中的每个元素都是一个函数指针变量,都可以存储函数入口的地址
  2. 能够实现对函数的批量调用
  3. 定义格式:返回值类型 (* 数组名[数组长度])(形参列表)

二级指针

  1. 每个指针变量都占有内存空间,有空间就有地址,就可以使用指针存储他的地址
  2. 存储一级指针变量的地址的指针变量就是二级指针变量
    一级指针变量的地址为二级指针
  3. 定义格式:数据类型 **指针名
  4. 二级指针变量的值为:一级指针变量的地址
    二级指针指向的内存空间中的值是一级指针(也就是变量的地址)—> *二级指针变量
    二级指针取值两次是变量的值 —> **二级指针变量
  5. 二级指针变量常用于函数参数为主程序中的一级指针变量进行赋值

万能指针

  1. 万能指针就是可以接收任意地址的指针变量
  2. 定义格式:void *指针名
  3. 由于没有任何类型的限制,导致该指针变量可以接收任意类型的地址
  4. 对于万能指而言不能直接进行*运算

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com