浅学指针(3)

简介: 浅学指针(3)

前言

系列文章目录

前言

学习字符指针变量,数组指针变量,函数指针变量,函数指针数组,三个变量要有所理解,还有、函数指针数是重点内容。


1. 字符指针变量

为了加强理解。来我们来看如下代码:


int main()
{
  const char* pstr = "hello bit.";//这⾥是把⼀个字符串放到pstr指针变量⾥了吗?
  printf("%s\n", pstr);
  return 0;
}


其实并不是这样的,他是像字符串一样,把首字符的地址放到指针pstr里面了,为了让你们理解,如图:

3a92fd63f16942cda2d3795aecfd1fda.png

扩展⼀道和字符串相关的笔试题


#include <stdio.h>
int main()
{
  char str1[] = "hello bit.";
  char str2[] = "hello bit.";
  const char *str3 = "hello bit.";
  const char *str4 = "hello bit.";
  if(str1 ==str2)
    printf("str1 and str2 are same\n");
  else
    printf("str1 and str2 are not same\n");
  if(str3 ==str4)
    printf("str3 and str4 are same\n");
  else
    printf("str3 and str4 are not same\n");
 return 0;
}



运行结果:

b7b3c928745341ce9e773990d9a49e2b.png

这是为什么呢?其实,这⾥str3和str4指向的是⼀个同⼀个常量字符串,C/C++会把常量字符串存储到单独的⼀个内存区域,当⼏个指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存。但是⽤相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4相同。


2. 数组指针变量

数组指针数组指针,强调的是指针,怎么理解呢?

(1)整形指针变量: int * pint; 存放的是整形变量的地址,能够指向整形数据的指针。

(2)浮点型指针变量: float * pf; 存放浮点型变量的地址,能够指向浮点型数据的指针。


那数组指针变量应该是:存放的应该是数组的地址,能够指向数组的指针变量。

那么我们来理解两句代码:


int *p1[10];
  int (*p2)[10];


思考一下p1,p2分别是什么?

正确答案是:p1是数组指针,p2是指针数组


怎么理解,这⾥要注意:[]的优先级要⾼于*号的,但是()优先级高于[ ],所以可以利用优先级理解,就如上面代码:

p1:[ ]的优先级高于 星号的,先和[ ]结合,说明p1是数组,数组10个元素,每个元素的类型是int *,所以p1是指针数组。

p2:( )的优先级高于[ ],*p2则说明p2是指针,在和[ ]结合说明是数组,所以p2是数组指针。


2.2 数组指针变量怎么初始化

数组指针变量是⽤来存放数组地址的,那怎么获得数组的地址呢?就是我们之前学习的 &数组名,这是整个数组放入。


操作如下:


int(*p)[10] = &arr;


调试下:

31e31f12fd604cf381021bc8981ced2b.png

看到 &arr 和 p 的类型是完全⼀致的。


总结:函数名就是地址,&函数名和直接使用函数名是一样的。

数组指针类型解析:


int  (*p)  [10] = &arr;
   |    | |
   |    | |
   |    |    p指向数组元素个数
   |    p是数组指针变量名
   p指向的数组的元素类型


3 .函数指针变量

函数指针变量是⽤来存放函数地址的,未来通过地址能够调⽤函数的。

函数是有地址的,函数名就是函数的地址,当然也可以通过 &函数名 的⽅式获得函数的地址,如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指针⾮常类似。如下:


//第1种
void test()
{
  printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)()= test;
//第2种
int Add(int x, int y)
{
  return x+y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add;//x和y写上或者省略都是可以的


函数指针类型解析:


int  (*p) (int x, int y)
   |    | |
   |    | |
   |    |    pf3指向函数的参数类型和个数的交代,
   |    函数指针变量名
   pf3指向函数的返回类型
  int (*) (int x, int y) //pf3函数指针变量的类型


3.1 函数指针变量的使⽤

通过函数指针调⽤指针指向的函数


#include <stdio.h>
int Add(int x, int y)
{
  return x+y;
}
int main()
{
  int(*pf3)(int, int) = Add;
  printf("%d\n", (*pf3)(2, 3));
  printf("%d\n", pf3(3, 5));//*在这里可有可无因为函数名也是函数地址
 return 0;
}


输出结果:

5

8


4 .typedef关键字

ypedef 是⽤来类型重命名的,可以将复杂的类型,简单化。


⽐如,你觉得 unsigned int 写起来不⽅便,如果能写成 uint 就⽅便多了,那么我们可以使⽤:


typedef unsigned int uint;
  //将unsigned int 重命名为uint


果是指针类型,能否重命名呢?其实也是可以的,⽐如,将 int* 重命名为 ptr_t ,这样写:


typedef int* ptr_t;
  //将int * 重命名为 ptr_t


数组指针和函数指针稍微有点区别:

数组指针类型 int(*)[5] ,需要重命名为 parr_t ,那可以这样写:


typedef int(*parr_t)[5]; //新的类型名必须在*的右边


函数指针类型的重命名也是和数组指针类型⼀样的,⽐如,将 void(*)(int) 类型重命名为 pf_t ,就可以这样写:


typedef void(*pfun_t)(int);//新的类型名必须在*的右边


练习:


代码1:(*(void (*)())0)();
代码2:void (*signal(int , void(*)(int)))(int);


那么要简化代码,可以这样写:


xtypedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);


5. 函数指针数组

数组是⼀个存放相同类型数据的存储空间,我们已经学习了指针数组,如:


int *arr[10];
  //数组的每个元素是int*


那要把函数的地址存到⼀个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?


int (*parr1[3])();


可以向之前利用优先级理解,第1()里面是指针数组,把parr1

[3]删除后是int (* )()是函数指针,如图:


38936194810b46b385689b7ba04d02c4.png

目录
打赏
0
0
0
0
1
分享
相关文章
python-包及日志模块使用
一、包 1.包就是一个保护有__init__.py文件的文件夹,包的本质就是一种模块,即包是用来导入使用的,包内部包含的文件也都是用来被导入使用的.包是为了更好组织好模块,就是一个文件夹. 注:在python2中,包下必须有一个__init__.
1104 0
[LeetCode] Candy
Well, you may need to run some examples to have the intuition for the answer since we only require children with higher rating get more candies than their neighbors, not all those with lower ratings.
808 0
深度评测 | 仅用3分钟,百炼调用满血版 Deepseek-r1 API,百万Token免费用,简直不要太爽。
仅用3分钟,百炼调用满血版Deepseek-r1 API,享受百万免费Token。阿里云提供零门槛、快速部署的解决方案,支持云控制台和Cloud Shell两种方式,操作简便。Deepseek-r1满血版在推理能力上表现出色,尤其擅长数学、代码和自然语言处理任务,使用过程中无卡顿,体验丝滑。结合Chatbox工具,用户可轻松掌控模型,提升工作效率。阿里云大模型服务平台百炼不仅速度快,还确保数据安全,值得信赖。
157353 24
深度评测 | 仅用3分钟,百炼调用满血版 Deepseek-r1 API,百万Token免费用,简直不要太爽。
用DeepSeek,就在阿里云!四种方式助您快速使用 DeepSeek-R1 满血版!更有内部实战指导!
DeepSeek自发布以来,凭借卓越的技术性能和开源策略迅速吸引了全球关注。DeepSeek-R1作为系列中的佼佼者,在多个基准测试中超越现有顶尖模型,展现了强大的推理能力。然而,由于其爆火及受到黑客攻击,官网使用受限,影响用户体验。为解决这一问题,阿里云提供了多种解决方案。
16985 37
PAI Model Gallery 支持云上一键部署 DeepSeek-V3、DeepSeek-R1 系列模型
DeepSeek 系列模型以其卓越性能在全球范围内备受瞩目,多次评测中表现优异,性能接近甚至超越国际顶尖闭源模型(如OpenAI的GPT-4、Claude-3.5-Sonnet等)。企业用户和开发者可使用 PAI 平台一键部署 DeepSeek 系列模型,实现 DeepSeek 系列模型与现有业务的高效融合。
本地部署DeepSeek模型
要在本地部署DeepSeek模型,需准备Linux(推荐Ubuntu 20.04+)或兼容的Windows/macOS环境,配备NVIDIA GPU(建议RTX 3060+)。安装Python 3.8+、PyTorch/TensorFlow等依赖,并通过官方渠道下载模型文件。配置模型后,编写推理脚本进行测试,可选使用FastAPI服务化部署或Docker容器化。注意资源监控和许可协议。
1310 8
手把手教你使用 Ollama 和 LobeChat 快速本地部署 DeepSeek R1 模型,创建个性化 AI 助手
DeepSeek R1 + LobeChat + Ollama:快速本地部署模型,创建个性化 AI 助手
3416 117
手把手教你使用 Ollama 和 LobeChat 快速本地部署 DeepSeek R1 模型,创建个性化 AI 助手
DeepSeek全尺寸模型上线阿里云百炼!
阿里云百炼平台近日上线了DeepSeek-V3、DeepSeek-R1及其蒸馏版本等六款全尺寸AI模型,参数量达671B,提供高达100万免费tokens。这些模型在数学、代码、自然语言推理等任务上表现出色,支持灵活调用和经济高效的解决方案,助力开发者和企业加速创新与数字化转型。示例代码展示了如何通过API使用DeepSeek-R1模型进行推理,用户可轻松获取思考过程和最终答案。
如何在通义灵码里用上DeepSeek-V3 和 DeepSeek-R1 满血版671B模型?
除了 AI 程序员的重磅上线外,近期通义灵码能力再升级全新上线模型选择功能,目前已经支持 Qwen2.5、DeepSeek-V3 和 R1系列模型,用户可以在 VSCode 和 JetBrains 里搜索并下载最新通义灵码插件,在输入框里选择模型,即可轻松切换模型。
934 14
阿里云PAI部署DeepSeek及调用
本文介绍如何在阿里云PAI EAS上部署DeepSeek模型,涵盖7B模型的部署、SDK和API调用。7B模型只需一张A10显卡,部署时间约10分钟。文章详细展示了模型信息查看、在线调试及通过OpenAI SDK和Python Requests进行调用的步骤,并附有测试结果和参考文档链接。
1938 9
阿里云PAI部署DeepSeek及调用

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等