首页 > 其他分享 >C Pointer plus

C Pointer plus

时间:2023-05-27 22:44:34浏览次数:25  
标签:函数 int 运算符 双目 plus Pointer 表达式 库函数

高级指针

补充回顾

标量:这个名称似乎是《C和指针》的特有名词,他是为了区分数组而产生,数组可以通过下标或者数组名间接访问,可以理解为向量,而标量则与其相反,例如结构体,但是在某些博客上,则认为标量是指枚举类型、字符类型以及整数类型

指向指针的指针

int i;
int *pi;
int **pii;
pi=&a;
pii=π
//通过以上赋值语句,可以使下列三条赋值语句等价
i='a';
*pi='a';
**pii='a';

高级声明

int *f;//将*f声明为整数,因此f为指向整型的指针
int *f();//函数调用操作符的优先级高于间接访问操作符,所以先执行函数调用,因此返回值为int*
int (*f)()//函数指针,先执行小括号,函数指针的基本类型为 void (*变量名)()
int* (*f)()//依然为函数指针,只不过上一个返回类型为int,而这一个为int*
int  f[ ]//整型数组f
int  *f[ ]//数组名为f,数组类型为指向整型的指针
int  f()[ ]//这个声明是不合法,因为f会与()相结合形成函数,那么其返回类型为整型数组,是非法的
int  f[ ]()//[ ]和()的结合性从左向右,所以这是一个数组,类型为返回类型为整型的函数,但是这个声明是非法,因为数组元素的长度            必须相等,而不同的函数的长度显然不相等
int (*f[ ])()//这个与上一个的目的类似,但是说这一次的数组类型为函数指针,尽管不同函数的长度可能不同,但是其指针长度是一致的
int* (*f[ ])()//这个与上一个函数的目的类似,只是这一函数采用了返回指向整数的指针的方法,也就是说这一次的数组类型为函数指针 //展示两个例子
int (*f)(int,float)
int* (*g[])(int,float)

函数指针

int f(int);
int (*pf)(int);
pf=&f;//实际上这里的&操作符是可选的,因为f函数名的本质是函数指针,指针指向函数代码区域的起始部分
//以下是三种调用方式
f(1);//直接调用
(*pf)(1);//间接访问
pf(1);//实际上函数调用时,函数名会隐式转换为函数指针,而此表达式则将此过程显式表达了

回调函数

回调函数是一种技巧,用户将函数指针作为函数参数传入,函数反过来调用用户的函数,回调函数主要应用于两种情况,一种是所编写的函数需要在不同时刻执行不同类型的工作,另一种则是只能执行函数调用者定义的工作

回调函数的使用

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
typedef struct node{
    int a;
    struct node* b;
}node;
//不使用函数回调的情况
//node* search_(node* a1, int const val)
//{
//    while (a1 != NULL)
//    {
//        if (a1->a == val)
//            break;
//        a1 = a1->b;
//    }
//    return a1;
//}
//使用函数回调的情况
int compare(void const* a, void const* b)
{
    if (*(int*)a == *(int*)b)
        return 0;
    else
        return 1;
}
node* search_(node* a1, int const val,int (*abx)(void const*a1,void const *val))
{
    while (a1 != NULL)
    {
        if (abx(&a1->a,&val)==0)
            break;
        a1 = a1->b;
    }
    return a1;
}
int main()
{
    node c, d, e, f, g;
    node* head;
    c.a = 1;
    d.a = 2;
    e.a = 3;
    f.a = 4;
    g.a = 5;
    head = &c;
    c.b = &d;
    d.b = &e;
    e.b = &f;
    f.b = &g;
    node* phead = head;
    int (*abx)(void const*, void const*) = &compare;
    phead = search_(head, 3,abx);
    printf("%d", phead->a);
    return 0;
}

回调函数的好处

回调似乎只是函数间的调用,和普通函数调用没啥区别,但仔细一看,可以发现两者之间的一个关键的不同:在回调中,主程序把回调函数像参数一样传入库函数。这样一来,只要我们改变传进库函数的参数,就可以实现不同的功能,这样有没有觉得很灵活?并且丝毫不需要修改库函数的实现,这就是解耦。再仔细看看,主函数和回调函数是在同一层的,而库函数在另外一层,想一想,如果库函数对我们不可见,我们修改不了库函数的实现,也就是说不能通过修改库函数让库函数调用普通函数那样实现,那我们就只能通过传入不同的回调函数了,这也就是在日常工作中常见的情况。

转移表

回调函数的好处

回调似乎只是函数间的调用,和普通函数调用没啥区别,但仔细一看,可以发现两者之间的一个关键的不同:在回调中,主程序把回调函数像参数一样传入库函数。这样一来,只要我们改变传进库函数的参数,就可以实现不同的功能,这样有没有觉得很灵活?并且丝毫不需要修改库函数的实现,这就是解耦。再仔细看看,主函数和回调函数是在同一层的,而库函数在另外一层,想一想,如果库函数对我们不可见,我们修改不了库函数的实现,也就是说不能通过修改库函数让库函数调用普通函数那样实现,那我们就只能通过传入不同的回调函数了,这也就是在日常工作中常见的情况。

转移表

 

 

命令行参数

C语言程序main函数有两个参数argc和argv,argc表示命令行参数数目,argv用来存储一组参数值,因为argc的数目没有内在限制,所以argv指向这组参数值的首元素(本质上是数组)的第一个元素,这些元素的每一个都是指向一个参数文本的指针,main在声明时就要加上一些参数:int main(int argc,char**argv)

这里的char**argv就相当于char *argv[ ]

字符串常量

当一个字符串常量出现在表达式中时,其值为指针常量,指针指向字符串的第一个字符,,编译器将字符串的一份副本存储在内存的某个位置,并保留了一份指向第一份字符的指针

"xyz"+1//y
*"xyz"//x
"xyz"[2]//z
putchar("0123456789ABCDEF"[values%16])//简洁实现二进制变字符,values为源数

附录(运算符表)

优先级运算符名称或含义使用形式结合方向说明
1 [] 数组下标 数组名[常量表达式] 左到右  
() 圆括号 (表达式) 函数名(形参表)      
. 成员选择(对象) 对象.成员名      
-> 成员选择(指针) 对象指针->成员名      
2 - 负号运算符 -表达式 右到左 单目运算符
(类型) 强制类型转换 (数据类型)表达式      
++ 自增运算符 ++变量名 变量名++ 单目运算符    
-- 自减运算符 --变量名 变量名-- 单目运算符    
* 取值运算符 *指针变量 单目运算符    
& 取地址运算符 &变量名 单目运算符    
! 逻辑非运算符 !表达式 单目运算符    
~ 按位取反运算符 ~表达式 单目运算符    
sizeof 长度运算符 sizeof(表达式)      
3 / 表达式 / 表达式 左到右 双目运算符
* 表达式*表达式 双目运算符    
% 余数(取模) 整型表达式%整型表达式 双目运算符    
4 + 表达式+表达式 左到右 双目运算符
- 表达式-表达式 双目运算符    
5 << 左移 变量<<表达式 左到右 双目运算符
>> 右移 变量>>表达式 双目运算符    
6 > 大于 表达式>表达式 左到右 双目运算符
>= 大于等于 表达式>=表达式 双目运算符    
< 小于 表达式<表达式 双目运算符    
<= 小于等于 表达式<=表达式 双目运算符    
7 == 等于 表达式==表达式 左到右 双目运算符
!= 不等于 表达式!= 表达式 双目运算符    
8 & 按位与 表达式&表达式 左到右 双目运算符
9 ^ 按位异或 表达式^表达式 左到右 双目运算符
10 | 按位或 表达式|表达式 左到右 双目运算符
11 && 逻辑与 表达式&&表达式 左到右 双目运算符
12 || 逻辑或 表达式||表达式 左到右 双目运算符
13 ?: 条件运算符 表达式1? 表达式2: 表达式3 右到左 三目运算符
14 = 赋值运算符 变量=表达式 右到左  
/= 除后赋值 变量/=表达式      
*= 乘后赋值 变量*=表达式      
%= 取模后赋值 变量%=表达式      
+= 加后赋值 变量+=表达式      
-= 减后赋值 变量-=表达式      
<<= 左移后赋值 变量<<=表达式      
>>= 右移后赋值 变量>>=表达式      
&= 按位与后赋值 变量&=表达式      
^= 按位异或后赋值 变量^=表达式      
|= 按位或后赋值 变量|=表达式      
15 , 逗号运算符 表达式,表达式,… 左到右  

标签:函数,int,运算符,双目,plus,Pointer,表达式,库函数
From: https://www.cnblogs.com/alexlance/p/17437503.html

相关文章

  • 【cplusplus教程翻译】指针(Pointers)
    在前面的章节中,变量被解释为计算机内存中的位置,可以通过其标识符(名称)访问这些位置。这样,程序就不需要关心内存中数据的物理地址;只要需要引用变量,它就简单地使用标识符。对于C++程序来说,计算机的内存就像一系列的存储单元,每个存储单元的大小都是一个字节,并且每个存储单元都有一个......
  • MapStructPlus 1.2.5 发布,新增 Solon 支持
    MapStructPlus1.2.5发布,更新内容如下:fix:解决MapConvertMapperAdapter编译警告问题feat:增加nullValueMappingStrategy和nullValuePropertyMappingStrategy配置项feat:适配solon主要更新内容为适配Solon,使用方式基本等同于SpringBoot环境下的使用方式。与其......
  • mybatis-plus
    mybatis-plus是一款Mybatis增强工具,用于简化开发,提高效率。下文使用缩写mp来简化表示mybatis-plus,本文主要介绍mp搭配SpringBoot的使用。注:本文使用的mp版本是当前最新的3.4.2,早期版本的差异请自行查阅文档官方网站:baomidou.com/快速入门创建一个SpringBoot项目导入依赖......
  • MybatisPlusGenerator 实体类 xml dao 生成工具
    packagecom.thtf.zwdsj.gongjia.config;importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.baomidou.mybatisplus.generator.FastAutoGenerator;importcom.baomidou.mybatisplus.generator.config.OutputFile;importcom.baomidou.mybatisplus.gener......
  • ADManager Plus:微软的全面活动目录管理解决方案
    摘要:ADManagerPlus是微软推出的一款全面活动目录(ActiveDirectory)管理解决方案。它提供了一系列强大的功能,帮助组织简化和自动化活动目录管理,提高安全性和效率。本文将介绍ADManagerPlus的特点、优势以及在企业中的应用价值。微软的ADManagerPlus是一款功能强大的全面活动目录管......
  • HDU 1024 Max Sum Plus Plus(动态规划)
    传送门题意是给你个数字序列,现在让你把这个序列分成m个连续的子序列,且要求这m个子序列的累加和最大。思路:这道题的题意可以理解为问在序列为末尾时,把序列分为m个子序列这个状态时的最大累加和,那么可以得出这个状态应该是由上一个状态转移得来:(因为dp[i][j]表示数到第j个字符时,前j个......
  • elementplus vue3 ts 单图预览封装
    <divclass="demo-image__preview"><el-imagestyle="width:50px":src="props.image":zoom-rate="1.2":preview-src-list="[props.image]":initial-index="4&quo......
  • MyBatisPlus踩坑
    背景:当一个外部系统调用我们一个免登录的API接口,在我们数据库去保存或更新一条数据时,库表中的创建人和更新人字段不是正确的值。但是代码层面我们是有正确的设置创建人和更新人,查询sql日志发现我们设置的值统一被替换为“admin”了。这个时候才明白为什么另一个接口中在保存完......
  • Mybatis-Plus自动生成代码,自定义Controller
    MP网址:https://baomidou.com/pages/779a6e/#%E4%BD%BF%E7%94%A8直接copy官网代码修改成自己的:privatevoidgenerate(){FastAutoGenerator.create("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2b8","root","P@ss123.")......
  • 解决vue3自动引入element-plus后eslint警告
    配置vue.config.js......module.exports=defineConfig({......configureWebpack:{plugins:[AutoImport({resolvers:[ElementPlusResolver()],eslintrc:{enabled:true,filepath:"./.eslintrc-auto......