当前位置:网站首页>C语言-7月31日-指针的总结以及typedef关键字
C语言-7月31日-指针的总结以及typedef关键字
2022-08-11 05:30:00 【曾铎000811】
目录
引入typedef关键字:
在这里有几行代码,为了方便快捷起见,我意图只通过一个指针的操作符实现对指针变量的重复定义:
#include<stdio.h>
int main()
{
int c = 0;
int *a,b;
a = &c;
b = &c;
return 0;
}结果编译器报错:

报错原因:不能将“int *”类型的值分配到int 类型的实体,可见,b还是一个整形值,不能存放c的地址,这样书写是错误的。
这时我们想到使用宏替换可不可以解决这一问题,试试看:
如果我们使用宏替换:将int *用宏替换成Point_32然后再来执行这种语句会有什么样的结果呢?
#define Point_32 int*
#include<stdio.h>
int main()
{
int c = 0;
Point_32 a,b;
a = &c;
b = &c;
return 0;
}依然报错:

所以宏在预编译时本质上就是一个字符串替换,在此处可以体现。
在C语言中支持一种叫做typedef的机制,它允许你对各种数据类型定义新名字,typedef和宏替换的书写方法是相反的,例如上面我要将int*替换为Point_32,使用typedef这样书写:typedef int* Point_32
引入typedef,类型的重命名,我们再来看看结果:

注意此时a和b的基类型都为int,a和b都为整形类型的指针。
这时程序并没有报错,预编译成功。
指针的总结:
数组指针:一个指向数组的指针
在这里我定义一个二维数组:
int ar[3][4] = {0};可以知道,这个二维数组三行四列,那么我们如何定义一个指针,使它指向这个二维数组?
指向二维数组共有三种典型的情况,分别是指针指向二维数组的一行;

指针指向二维数组中的一个元素;

指针指向整个二维数组;

以上为三种情况,我们通过代码进行实现:
#include<stdio.h>
int main()
{
int ar[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4] = ar;
//p++ p加4个int类型,也就是一行数据
int (*p)[4] = &ar[0];
//p++ p加4个int类型,也就是一行数据
int *p = &ar[0][0];
//p++ p加1个int类型,也就是一行中的一个数据
int (*p)[3][4] = &ar;
//p++ p加12个int类型,也就是整个二维数组
return 0;
}我们使用typedef对数组指针重命名:
typedef int(*Arr_Point)[4];当我们在使用typedef进行类型的重命名时,需谨记,typedef后面的依次是类型以及你要重新定义的类型名:
typedef long long int int_64;注意,此时的int_64就是我们要重新定义的类型名,前面的long为8字节,三个类型大小相乘的结果为64.
指针数组:一个保存指针类型数据的数组
例如在这里我给出一个数组,用来存储指针。

代码:
#include<stdio.h>
int main()
{
const char* str[2] = {"hello","world"};
const char **p = &str[0];
printf("%s,%s\n",*(p),*(p + 1));
return 0;
}在这段代码中,str是一个存放了两个指针变量的数组,两个指针变量分别指向hello和world的首地址,例如在这里我定义了一个二级指针p用于存放两个数组中存放的一级指针变量的地址,当我对二级指针p和(p + 1)分别进行解引用时,他们分别指向的是:

如图,分别打印出了hello和world,此时对二级指针解引用加1,所指向的应该是一整个单元格,也就是从hello字符串的首地址直接跳向world的首地址。
那么如何解引用指针再加一使它只向前迁移一个字符呢?
#include<stdio.h>
int main()
{
const char* str[2] = {"hello","world"};
const char *p = str[0];
printf("%s,%s\n",(p),(p + 1));
return 0;
}如图我对主程序进行了修改,将p替换为了一级指针,此时我令一级指针p指向str中的第一个字符串hello存放hello字符串的首地址,接下来我分别对指针p和p + 1进行解引用并打印,我们再来看看结果:

如图,分别打印出了hello和ello说明p指针发生了偏移,而且是一个字符!我们再来试试使用p指针指向第二个字符串的首地址然后打印:

如图,分别打印出了world字符串和字符串指针向后偏移一位的后续字符,这说明一级指针p此时如果加一,偏移量是一个字符。
函数指针(指向函数的指针):
#include<stdio.h>
#include<string.h>
int add(int a,int b)
{
return a + b;
}
int mul(int a,int b)
{
return a * b;
}
int main()
{
int a,b;
char op[10] = {0};
scanf("%d%d",&a,&b);
scanf("%c",&op);
//定义一个函数指针,指向add,指向mul
int (*pfun)(int,int);//声明指针变量
//函数指针类型
if(strcmp(op,"+") == 0){
pfun = add;
}
else{
pfun = mul;//指针指向栈对mul函数开辟的空间的起始位置
}
int result = fun(a.b);
printf("%d\n",result);
return 0;
}在这里我定义了一个*pfun的指针变量,用来指向add和mul函数,意图实现分别输入数据再输入相应的运算符,返回相应的运算结果。
我们将函数指针与typedef进行结合使用(重点):
typedef int (*pfun)(int,int);
#include<stdio.h>
int add(int a,int b)
{
return a + b;
}
int mul(int a,int b)
{
return a * b;
}
int main()
{
pfun p = mul;
int result = p(2,3);
printf("result = %d\n",result);
return 0;
}在这里我对pfun进行了类型重命名,分别写了两个两数之和(add)和两数之积()的函数,在主函数中定义了p指针并使p指针指向了两数之积(mul)函数 ,我们来看看运行结果:

输入输出函数组:
getchar();
putchar();
scanf();
printf();
gets();
puts();在这里给出一个程序:
#include<stdio.h>
int main()
{
int a;
char c;
scanf("%d",&a);
printf("%d\n",a);
scanf("%c",&c);
printf("%c\n",c);
return 0;
}我意图第一次输入整形值a并打印,然后再输入字符c,再打印字符c,我们来看运行结果:

程序在我输入整形值2并打印出来后,直接结束了, 并没有让我继续输入字符,为什么会出现这种情况呢?
在使用scanf函数时,存在一个输入缓冲区,当我们输入%d和%c类型时,中间是以“\n”分隔开的,输入缓冲区分不清\n到底是哪种性质,所以就会选择直接结束程序,我们只需要在两种类型的输入输出语句间添加一句getchar();就可以将问题解决:

输出完成
边栏推荐
- 父子节点数据格式不一致的树状列表实现
- 开源机器学习数据库OpenMLDB贡献者计划全面启动
- Building a data ecology for feature engineering - Embrace the open source ecology, OpenMLDB fully opens up the MLOps ecological tool chain
- JS进阶网页特效(pink老师笔记)
- stack stack
- 论文解读TransFG: A Transformer Architecture for Fine-grained Recognition
- Fourth Paradigm OpenMLDB optimization innovation paper was accepted by VLDB, the top international database association
- Vscode远程连接服务器终端zsh+Oh-my-zsh + Powerlevel10 + Autosuggestions + Autojump + Syntax-highlighting
- Open Source Machine Learning Database OpenMLDB Contributor Program Fully Launched
- 使用c语言实现井字棋(有源码,可以直接运行)
猜你喜欢
随机推荐
C language implementation guess Numbers (with source code, can be directly run)
微信小程序_开发工具的安装
The official website of OpenMLDB is upgraded, and the mysterious contributor map will take you to advance quickly
Node 踩坑之80端口被占用
SearchGuard configuration
JS小技巧,让你编码效率杠杠的,快乐摸鱼
OpenMLDB: Consistent production-level feature computing platform online and offline
He Kaiming's new work ViTDET: target detection field, subverting the concept of layered backbone
本地服务配置内网穿透实现微信公众号整合
Event Preview | On April 23, a number of wonderful sharing sessions of OpenMLDB will come, which will live up to the good time of the weekend
C语言实现简易扫雷(附带源码)
USB URB
贡献者任务第三期精彩来袭
ARM assembly instruction ADR and LDR
Jetpack之dataBinding
基于微信小程序云开发实现的电商项目,可以自行定制开发
heap2 (tcache attack,house of orange)
论文解读:GAN与检测网络多任务/SOD-MTGAN: Small Object Detection via Multi-Task Generative Adversarial Network
stack stack
js learning advanced (event senior pink teacher teaching notes)









