【C初阶——指针3】鹏哥C语言系列文章,基本语法知识全面讲解——指针(3)

本文由@睡觉待开机原创,转载请注明出处。
本内容在csdn网站首发
欢迎各位点赞—评论—收藏
如果存在不足之处请评论留言,共同进步!

这里写目录标题

  • 前言:
  • 1.字符指针变量
    • 1.1一般用法
    • 1.2指向常量字符串
  • 2.数组指针变量
    • 2.1数组指针变量的概念
    • 2.2数组指针使用举例:二维数组传参的本质
  • 3.函数指针
    • 3.1函数指针的介绍:
    • 3.2函数指针的典例:
    • 3.3sypedef关键字
  • 4.函数指针数组
    • 4.1函数指针数组介绍
    • 4.2函数指针数组的典例:转移表

思路大纲:
在这里插入图片描述

前言:

本节博客我们继续进一步来探讨指针初阶相关问题。

1.字符指针变量

在这里插入图片描述

字符指针,char*有两种用法。

1.1一般用法

一般来说,char*指针指向的是类型为char的数据类型,这是一种用法(如下)。

int main()
{char a = 'a';char* p = &a;return 0;
}

1.2指向常量字符串

其实还有一种使用方法:字符指针用来作为指向字符串常量。
示例如下:

#include<stdio.h>
int main()
{/*char a = 'a';char* p = &a;*/char* p = "abcdef";printf("%s\n", p);return 0;
}

在这里插入图片描述
当然应该如何去理解这个代码呢?且听我细细道来。
首先这里有个误区哈,可能很多人认为上面那段代码是把字符串abcdef放到指针p中了,但是本质是把字符串abcdef的首字母地址放到p中。
在这里插入图片描述
同时,我还要强调的是,编译器在处理常量字符串时候如果常量字符串完全相同,往往会优化为只保存一份。
下面是关于该问题的例证:

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

结果如下:
在这里插入图片描述
解释:
这⾥str3和str4指向的是⼀个同⼀个常量字符串。C/C++会把常量字符串存储到单独的⼀个内存区域,
当⼏个指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存。但是⽤相同的常量字符串去初始
化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4相同。

2.数组指针变量

2.1数组指针变量的概念

什么是数组指针?那他是指针呢还是属于数组呢?是指针。
数组指针:是指指向数组的指针变量

2.2数组指针使用举例:二维数组传参的本质

//二维数组传参的本质
#include <stdio.h>
void test(int(*p)[5], int r, int c)
{int i = 0;int j = 0;for (i = 0; i < r; i++){for (j = 0; j < c; j++){printf("%d ", *(*(p + i) + j));}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };test(arr, 3, 5);return 0;
}

在这里插入图片描述
二维数组传参,可以写成数组的形式进行接收,也可以写成指针的形式进行接收。本质上,二维数组传参传的是每行的一维数组。
在这里插入图片描述

3.函数指针

3.1函数指针的介绍:

首先,我问个问题哈?函数有地址吗?
有地址哈。
在这里插入图片描述
如果我们要想把指针地址存起来,那就需要用到函数指针变量啦。

test()
{}
int main()
{test();printf("%p\n", &test);void (*p)(void) = &test;return 0;
}

在这里插入图片描述

#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;
}

在这里插入图片描述

3.2函数指针的典例:

(*(void (*)())0)();void (*signal(int , void(*)(int)))(int);

上面是两段比较有趣的代码,请分别进行解读。

首先,第一个是一个函数调用且听我细细道来,这个数字0强制转换为void(*)()类型,转变成地址为0的函数地址,然后进行解引用操作,调用该地址处的函数。

第二个代码:整体是一个函数,该函数名称为signal,参数共有两个,一个是int类型,另一个是函数指针类型,该函数指针类型参数为int返回类型为void,整体函数的返回值为函数指针类型,该函数指针类型是以int为参数类型,void为返回类型。

3.3sypedef关键字

这个是用来简化类型写法的关键字
在这里插入图片描述
但是这个地方有个写法需要注意哈,就是你要简略的带号,那简略后的标识符必须在号右边
比如:
typedef void(pfun_t)(int);//新的类型名必须在的右边
在这里插入图片描述

4.函数指针数组

4.1函数指针数组介绍

函数指针,这个概念咱们前面说过。
那函数指针数组是啥?是指针还是数组?是数组。
函数指针数组:指的是每个元素为函数指针的数组。

4.2函数指针数组的典例:转移表

啥是转移表?
转移表指的是函数指针数组,将函数指针数组作为一个跳板来连接不同的函数进行调用。
比如,下面我要编写一个简单的计算机程序:

#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a * b;
}
int div(int a, int b)
{return a / b;
}
int main()
{int x, y;int input = 1;int ret = 0;do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;case 3:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

在这里插入图片描述
但是,我们可以用转移表进行简短代码哈:

#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a * b;
}
int div(int a, int b)
{return a / b;
}
int main()
{int x, y;int input = 1;int ret = 0;int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);if ((input <= 4 && input >= 1)){printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = (*p[input])(x, y);printf("ret = %d\n", ret);}else if (input == 0){printf("退出计算器\n");}else{printf("输⼊有误\n");}} while (input);return 0;}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/326483.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式锁3: zk实现分布式锁4 使用临时顺序节点+watch监听+可重入(threadLocal)

一 zk实现分布式锁的可重入性 1.1 使用ThreadLocal属性 引入ThreadLocal线程局部变量保证zk分布式锁的可重入性。 1.2 关键代码说明 1.3 代码 1.3.1 初始化客户端 1.3.2 分布式锁代码 package com.atguigu.distributed.lock.config;import com.baomidou.mybatisplus.core…

《剑指 Offer》专项突破版 - 面试题 3 :前 n 个数字二进制形式中 1 的个数(C++ 实现)

目录 前言 方法一 方法二 方法三 前言 题目链接&#xff1a;338. 比特位计数 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 输入一个非负数 n&#xff0c;请计算 0 到 n 之间每个数字的二进制形式中 1 的个数&#xff0c;并输出一个数组。例如&#xff0…

thingsboard规则节点功能记录(自用)

本文是对【ThingsBoard源码级分析规则节点使用第一季】 https://www.bilibili.com/video/BV1CT411e7vt/?p4&share_sourcecopy_web&vd_source9a5ca7ed3cff97385fdab4b6188e485c 学习的一些记录&#xff0c;加深自己的理解&#xff0c;在此声明。 asset profile switch…

跨国制造业组网方案解析,如何实现总部-分支稳定互联?

既要控制成本&#xff0c;又要稳定高效&#xff0c;可能吗&#xff1f; 在制造企业积极向“智造”发展、数字化转型的当下&#xff0c;物联网、人工智能、机器人等新型设备加入到生产、管理环节&#xff0c;为企业内部数据传输提出了更高的要求。而当企业规模扩大&#xff0c;数…

用ChatGPT方式编程!GitHub Copilot Chat全面开放使用

全球著名开源分享平台GitHub在官网宣布&#xff0c;经过几个月多轮测试的GitHub Copilot Chat&#xff0c;全面开放使用&#xff0c;一个用ChatGPT方式写代码的时代来啦&#xff01; 据悉&#xff0c;Copilot Chat是基于OpenAI的GPT-4模型&#xff0c;再结合其海量、优质的代码…

小红书 X WSDM 2024「对话式多文档问答挑战赛」火热开赛!

基于大语言模型&#xff08;LLM&#xff09;的对话问答机器人&#xff0c;已经成为当前人工智能领域学术界和工业界共同关注的的热门研究方向之一。在对话过程中&#xff0c;为大模型引入搜索结果&#xff0c;进行检索增强的生成&#xff08;Retrieval Augmented Generation&am…

NVIDIA Jetpack6.0DP使用过程中的问题

Jetpack6.0DP是2023年12月才发布&#xff0c; 操作系统使用了ubuntu 22.04&#xff0c; gcc是11.4&#xff0c;版本都很高&#xff0c; 用起来还存在一些问题 无法使用jtop https://forums.developer.nvidia.com/t/jtop-no-longer-works-on-jp-6-0-dp/275215 使用$ sudo -H p…

写给自己的CSDN博客之旅-如何从过程中获取价值-

勇于尝试 一个普通人如何在竞争越来越激烈的现代社会找到安身立业的方式&#xff1f; 作为一个注册CSDN已经有19年的老人&#xff0c;这些年失败的经历实在是太多太多了。 虽然注册CSDN很早&#xff0c;但是写博客确是在工作之后&#xff0c;也就是2015年。 在此之前有很多失…

什么?谁?w (who what)

文章目录 什么&#xff1f;谁&#xff1f;w (who & what)默认的显示不显示标题行简洁模式显示更多信息 什么&#xff1f;谁&#xff1f;w (who & what) w可以认为是加强版的who&#xff0c;果然越简洁越强大&#xff0c;就比如less比more是功能更多的。 w不仅可以显示…

Linux 上 Nginx 配置访问 web 服务器及配置 https 访问配置过程记录

目录 一、前言说明二、配置思路三、开始修改配置四、结尾 一、前言说明 最近自己搭建了个 Blog 网站&#xff0c;想把网站部署到服务器上面&#xff0c;本文记录一下搭建过程中 Nginx 配置请求转发的过程。 二、配置思路 web项目已经在服务器上面运行起来了&#xff0c;运行的端…

[概率论]重生至期末考前一个月看我如何力挽狂澜(下)

课本为《概率论与数理统计》ISBN 978-7-301-29547-2&#xff0c;此次整理4-8章的内容。 第四章 随机变量的数字特征 期望 频率具有波动性&#xff0c;概率具有稳定性。 离散型 设X是离散型随机变量&#xff0c;其分布律为&#xff1a;P{Xxk}pk ,k0,1,2,…… 两点分布 E(X)…

JavaScrip-初识JavaScript-知识点

初识JavaScript 编程基础编程计算机语言标记语言编译器&解释器 计算机基础计算机组成数据存储数据存储单位程序运行 认识JavaScript什么是JavaScriptJavaScript作用HTML&CSS&JavaScript的关系浏览器执行JavaScript过程JavaScript的组成JavaScript初体验 JavaScript…