Hero Circle Shape
Hero Moon Shape
Hero Right Shape
tp下载注册|define是关键字吗

tp下载注册|define是关键字吗

  • 作者: tp下载注册
  • 2024-03-09 18:13:34

C语言初阶第五篇:讲一讲关键字,注意,define不是关键字哦 史上最全C语言关键字介绍(32个关键字全解析)_c语言define是合法关键字吗-CSDN博客

>

C语言初阶第五篇:讲一讲关键字,注意,define不是关键字哦 史上最全C语言关键字介绍(32个关键字全解析)_c语言define是合法关键字吗-CSDN博客

C语言初阶第五篇:讲一讲关键字,注意,define不是关键字哦 史上最全C语言关键字介绍(32个关键字全解析)

芝士工具猿

已于 2022-01-26 20:56:50 修改

阅读量4.9k

收藏

21

点赞数

39

分类专栏:

C语言基础

文章标签:

c语言

开发语言

后端

经验分享

于 2022-01-25 20:40:08 首次发布

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/awaitxm/article/details/122689458

版权

C语言基础

专栏收录该内容

12 篇文章

11 订阅

订阅专栏

雄关漫道真如铁,而今迈步从头越 老铁们,我们上一篇文章把操作符给说了一下,今天就开始关键字的介绍吧!绝对齐全,包你满意哦!

第五篇

一、初步认识32个关键字1、数据类型关键字2、程序语句关键字3、存储类型关键字4、其他关键字

二、部分关键字的使用演示1、auto2、enum3、goto4、register5、union6、volatile7、typedef8、static8.1、修饰局部变量8.2、修饰全局变量8.3、修饰函数

9、extern10、const

三、define的使用,定义常量和宏

关键字,是C语言本身提供给我们的,是我们不能创建的,常见的关键字有32个,我们来看一看:

一、初步认识32个关键字

1、数据类型关键字(12个) 2、控制语句关键字(12个) 3、存储类型关键字(4个) 4、其它关键字(4个)

1、数据类型关键字

关键字解释char声明字符型变量或函数返回值类型double声明双精度浮点型变量或函数返回值类型float声明浮点型变量或函数返回值类型int声明整型变量或函数long声明长整型变量或函数返回值类型short声明短整型变量或函数signed声明有符号类型变量或函数unsigned声明无符号类型变量或函数struct声明结构体类型union声明共用体类型enum声明枚举类型void声明函数无返回值或无参数,声明无类型指针

2、程序语句关键字

关键字解释for一种循环语句do循环语句的循环体while循环语句的循环条件break跳出当前循环continue结束当前循环,开始下一轮循环if条件语句else条件语句否定分支(与 if 连用)goto无条件跳转语句switch用于开关语句case开关语句分支default开关语句中的“默认”分支return子程序返回语句(可以带参数,也可不带参数)

3、存储类型关键字

关键字解释auto声明自动变量static声明静态变量extern声明变量或函数是在其它文件或本文件的其他位置定义register声明寄存器变量

4、其他关键字

关键字解释const声明只读变量sizeof计算数据类型或变量长度(即所占字节数)typedef用以给数据类型取别名volatile说明变量在程序执行中可被隐含地改变

二、部分关键字的使用演示

由于很多关键字我们都经常使用,所以这里演示一些可能出现频率没那么大的关键字:

1、auto

int main()

{

{

auto int a = 10;

}

printf("%d\n", a);

return 0;

}

auto大部分情况下都是被省略掉的。因为我们创建的变量本身就是自动变量,有自己的生命周期和工作区域。

2、enum

enum枚举关键字,读者可以看一看我写的C语言初阶第一篇的篇尾,链接在这里: C语言初阶第一篇

3、goto

goto语句允许把控制无条件转移到同一函数内的被标记的语句。我们现在基本上已经不使用这个语句了。在任何编程语言中,都不建议使用 goto 语句。因为它使得程序的控制流难以跟踪,使程序难以理解和难以修改。任何使用 goto 语句的程序可以改写成不需要使用 goto 语句的写法。

4、register

register,声明寄存器变量,这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。如果要了解它的真正作用,我们首先还得理解一下电脑的内存的问题: 那么寄存器,就是最上面的那个了,寄存器是集成到CPU上的,并不是那么容易就能被访问,所以只能是建议程序使用,而不能强制。所以,这段代码现在应该就理解了:

int main()

{

register int num = 10;//建议将num放到寄存器中

printf("%d\n", num);

return 0;

}//寄存器的使用一般用在非常高频访问的变量身上

5、union

union,声明共用体类型,这个关键字,就是声明一个变量,至于这个变量能干什么,我们需要学习了结构体的对齐才能有所了解,今天只简单的说一说:

//联合(共用体)

union Un

{

char c;

int i;

};//联合的大小至少是最大成员的大小

//当最大成员不是最大对齐数的整数倍时,就要对齐到整数倍

可能又有读者要问,那这个“对齐数”是啥?那么这里给出一个详细的解释链接: 结构体、结构体传参与其内存对齐、位段

6、volatile

volatile,说明变量在程序执行中可被隐含地改变,网上的搜索结果如下: volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访问。有兴趣的小伙伴可以去看看: C语言丨深入理解volatile关键字 我们平常基本使用不到这个关键字。

7、typedef

typedef,这个关键字我们一般用来给结构体起别名:

typedef struct StuInfo

{

//每个学生的个人信息包括:姓名、学号、籍贯、年龄、数学、英语、物理成绩

char name[15];

char address[20];

char ID[15];

int age;

int score[3];

int sum;

int order;

}StuInfo;

当然,也可以用来更改数据类型的名字:

#include

typedef int ElemDataType;

int main()

{

ElemDataType a = 10;

printf("%d\n", a);

return 0;

}

8、static

static,是用来修饰变量和函数的: 1、修饰局部变量,称为静态局部变量; 2、修饰全局变量,称为静态全局变量; 3、修饰函数,称为静态函数 我们先看两个代码的区别:

8.1、修饰局部变量

这个代码的运行结果是6 6 6 6 6 6 6 6 6 6

#include

void test()

{

int a = 5;

a++;

printf("%d ", a);

}

int main()

{

int i = 0;

while (i < 10)

{

test();

i++;

}

return 0;

}

而下面这个代码的结果是:6 7 8 9 10 11 12 13 14 15

#include

void test()

{

static int a = 5;

a++;

printf("%d ", a);

}

int main()

{

int i = 0;

while (i < 10)

{

test();

i++;

}

return 0;

}

没错,就是static,让局部变量变成了静态的局部变量,超出了局部的范围也不会销毁,会保留数据,下一次函数调用时依然存在。 static修饰的局部变量是存储在静态区的,有兴趣的小伙伴可以自行了解一下静态区、堆区、栈区的区别。

但是,static也不是随便用的,一个全局变量本来是具有外部链接属性的,但一旦被static修饰,外部链接属性就变成了内部链接属性,则只能在自己的源文件里使用,而不能在其他的文件内部使用:

8.2、修饰全局变量

例如,我们在script.c的源文件里声明一个静态全局变量 globalval,然后在test.c里尝试使用: 就会报错。

8.3、修饰函数

那么这个其实跟上面的修饰全局变量是非常相像的,函数本来是具有外部链接属性的,全局的函数加上static之后,就失去了外部链接的属性。就会在使用中报错: 不加static是可以使用的:

9、extern

extern是用来声明外部符号的,给个例子就理解了: 这样的代码时报错的,那么怎么更改?很简单,使用extern来声明外部符号: 这样就可以了。

10、const

const关键字,多见于函数的传参过程,因为传地址的效率更高一点,但是传地址会有一个缺点,就是又可能导致无意间修改了数据(因为给出地址是危险的行为)。所以const修饰之后,就会让使用安全很多。 不过const修饰的变量是一个常变量,详细的解释看笔者的这一篇文章: 从C语言发展历程到变量常量 点击这里,即可查看。

其他的关键字,基本大家都熟悉,就不多解释了。

三、define的使用,定义常量和宏

define应该是最容易被误认为是关键字的了,define并不是关键字,今天我们就顺便提一提define的使用吧!

define定义常量,我们见的都很多,其实没什么可说的,就给一个使用的案例代码吧:

#include

#define PI 3.14

int main()

{

int r = 10;

double area = 0;

area = (double)r * r * PI;

printf("%.2lf\n", area);

return 0;

}

关于定义宏,一般考试的实话可能会加以考察,我们只需要记住一句话: define只替换、不计算。

#include

#define Cau(a,b) a + b

int main()

{

int a = 10;

int b = 20;

int ret = 0;

ret = 2 * Cau(a, b);

printf("%d\n", ret);

return 0;

}

这个代码的结果是多少呢?结果是 40,为什么?因为define只替换,不计算,我们换一下看看: 2 * 10 + 20 = 40,40就是结果。

那么今天的分享就到这里了,希望本文对你有所帮助,老铁们我们下次再见。

优惠劵

芝士工具猿

关注

关注

39

点赞

21

收藏

觉得还不错?

一键收藏

知道了

24

评论

C语言初阶第五篇:讲一讲关键字,注意,define不是关键字哦 史上最全C语言关键字介绍(32个关键字全解析)

C语言32个关键字详解(包含非关键字define的使用)

复制链接

扫一扫

专栏目录

24 条评论

您还未登录,请先

登录

后发表或查看评论

芝士工具猿

CSDN认证博客专家

CSDN认证企业博客

码龄2年

暂无认证

45

原创

1万+

周排名

5万+

总排名

20万+

访问

等级

2282

积分

1659

粉丝

969

获赞

614

评论

1136

收藏

私信

关注

热门文章

C语言中阶第三篇:循环语句do while透析以及循环语句总结(执行次数、执行特点和循环英文的详解)

17668

C语言中阶第二篇:循环语句for透析(包含多条件判断和多变量控制)

12998

C语言实现哈夫曼压缩与解压缩的实现以及读取哈夫曼编码 万文长书,绝对详细哦

10471

Python深度学习:OpenCV图像处理实战 HSV处理,图像旋转平移(读书笔记)

10245

Python深度学习:Python数据处理及可视化(读书笔记)

10149

分类专栏

C语言基础

12篇

深度学习入门

6篇

C语言算法

1篇

Linux编程入门

3篇

笔记

4篇

随心记

3篇

最新评论

C语言实现哈夫曼压缩与解压缩的实现以及读取哈夫曼编码 万文长书,绝对详细哦

芝士工具猿:

都可以,看设计需求,数组方便

猴王问题(项目分析以及项目实现)

芝士工具猿:

是输入安全提示还是啥,得看是啥报错

猴王问题(项目分析以及项目实现)

瘦的良月有三:

为什么运行不出来求大佬指导

C语言中阶第四篇:分支与循环语句练习,求阶乘的多种方法(两层for循环求阶乘)、二分查找、字符串汇聚以及模拟用户登录

CSDN-Ada助手:

多亏了你这篇博客, 解决了问题: https://ask.csdn.net/questions/8034271, 请多输出高质量博客, 帮助更多的人

C语言实现哈夫曼压缩与解压缩的实现以及读取哈夫曼编码 万文长书,绝对详细哦

2301_80072885:

为什么要设置哈夫曼数组而不是链表呢

您愿意向朋友推荐“博客详情页”吗?

强烈不推荐

不推荐

一般般

推荐

强烈推荐

提交

最新文章

新篇幅-我在地球学python

C语言中阶第五篇:写一个强制关机的程序,以及goto语句跳出多层循环的应用

C语言详解生成随机数的过程,time函数、时间戳timer、rand函数和srand函数,附猜数字小游戏

2023年1篇

2022年37篇

2021年7篇

目录

目录

分类专栏

C语言基础

12篇

深度学习入门

6篇

C语言算法

1篇

Linux编程入门

3篇

笔记

4篇

随心记

3篇

目录

评论 24

被折叠的  条评论

为什么被折叠?

到【灌水乐园】发言

查看更多评论

添加红包

祝福语

请填写红包祝福语或标题

红包数量

红包个数最小为10个

红包总金额

红包金额最低5元

余额支付

当前余额3.43元

前往充值 >

需支付:10.00元

取消

确定

下一步

知道了

成就一亿技术人!

领取后你会自动成为博主和红包主的粉丝

规则

hope_wisdom 发出的红包

实付元

使用余额支付

点击重新获取

扫码支付

钱包余额

0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

百度知道 - 信息提示

百度知道 - 信息提示

百度首页

商城

注册

登录

网页

资讯

视频

图片

知道

文库

贴吧采购

地图更多

搜索答案

我要提问

百度知道>提示信息

知道宝贝找不到问题了>_

该问题可能已经失效。返回首页

15秒以后自动返回

帮助

 | 意见反馈

 | 投诉举报

京ICP证030173号-1   京网文【2023】1034-029号     ©2024Baidu  使用百度前必读 | 知道协议 

初识C语言—操作符,常见关键字,#define 定义常量和宏-CSDN博客

>

初识C语言—操作符,常见关键字,#define 定义常量和宏-CSDN博客

初识C语言—操作符,常见关键字,#define 定义常量和宏

J.Pei

已于 2024-03-05 22:54:53 修改

阅读量422

收藏

6

点赞数

7

文章标签:

c语言

于 2024-03-05 19:40:33 首次发布

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/Ochazuke/article/details/136487441

版权

前情提要,我们学到了操作符

单目操作符

!逻辑反操作-负值+正值&取地址sizeof操作数的类型长度(字节)~对前一个数二进制取反--前置,后置--++前置,后置++*间接访问操作符(解引用操作符)(类型)强制类型转换

单目操作符:只有一个操作数

按位取反 ~

int main()

{

   int a = 0;

   printf("%d", ~a);

   return 0;

}

输出结果

-1

按位取反,把所有二进制位中的数字取反(不考虑符号位)

0变成1,1变成0

0的二进制 00000000000000000000000000000000(32个比特位)

~a结果为 11111111111111111111111111111111

整数的二进制表示有三种

原码、反码、补码(针对负数),正整数:原码反码补码相同

-1:

10000000000000000000000000000001(最高位为符号位,)(-1的原码)

11111111111111111111111111111110(符号位不变,其他位取反)(-1的反码)

11111111111111111111111111111111(反码+1)(-1的补码)(内存中储存的是补码)

所以取反后我们得到的是数字的补码,并不是原码

int main()

{

   int a = 10;

   int b = ++a;//前置++

   printf("%d\n", b);

   printf("%d\n", a);

   return 0;

}

前置++,先++后使用

所以输出结果为

11

11

后置++

int main()

{

   int a = 10;

   int b = a++;//后置++

   printf("%d\n", b);

   printf("%d\n", a);

   return 0;

}

结果为

10

11

先使用,再++

强制类型转换

int main()

{

   int a = 3.14;

   printf("%d\n", a);

   return 0;

}

编译代码时出现警告,丢失精度,如何避免

int main()

{

   int a = (int)3.14;//强制类型转换

   printf("%d\n", a);

   return 0;

}

不推荐使用

关系操作符

>  >=  <  <=  !=  ==

很简单

逻辑操作符

&&  逻辑与  

||  逻辑或

int main()

{

   int a = 3;

   int b = 5;

   int c = a && b;

   //if(a && b)

   printf("%d\n", c);

   return 0;

}

输出结果为1

很简单的数学逻辑,不展开讲了,0为假,其他都为真

条件操作符

三木操作符

exp1?exp2 : exp3

exp1如果成立,exp2计算,整个表达式结果为exp2的结果

exp1如果不成立,exp3计算,整个表达式结果为exp3的结果

int main()

{

   int a = 0;

   int b = 3;

   int max = 0;

   max = a > b ? a : b;

   printf("%d\n", max);

   return 0;

}

输出结果为

3

逗号表达式

逗号隔开的一串表达式

int main()

{

   int a = 0;

   int b = 3;

   int c = 5;

   int d = (a = b + 2, c = a - 4, b = c + 2);

   printf("%d\n", d);

   return 0;

}

逗号表达式从左向右依次计算

真个表达式的结果是最后一个表达式的结果

输出结果

3

下标引用操作符、函数调用操作符,结构成员

[]   ()   .   ->

int main()

{

   int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

   printf("%d\n", arr[5]);//下标引用操作符

   return 0;

}

函数调用操作符

int main()

{

   printf("hehe\n");//调用函数的时候,函数名后面的圆括号

   return 0;

}

常见关键字

C语言提供 不能自己创建 关键字不能做变量名

auto  break  case  char const  continue default do double else enum

extern float for goto if int long register return short signed sizeof

static struct switch typedef union unsigned void volatile while

auto

自动的 - 每个局部变量都是auto修饰的

int main()

{

  {

       auto int a = 10;//自动创建 自动销毁 自动变量 一般省略auto

       //新的C语言语法中有其他用法,暂时不考虑

  }

   return 0;

}

extern

是用来声明外部符号

register

寄存器关键词

int main()

{

   register int num = 100;//建议num的值存放在寄存器中

   return 0;

}

仅仅是建议,具体放在那里还要看编译器

计算机中数据可以存放在哪里呢?

寄存器 更小 高速缓存 几十MB 内存 8-16G 硬盘 500G 网盘 2T

越往上,造价越高,速度越快,空间越小

CPU 中央处理器 —— 内存中读取

随着发展,CPU速度越来越快,内存速度可能跟不上,所以这个时候再快也变得没意义

我们在内存之上提供高速缓存和寄存器

CPU从寄存器拿,寄存器去高速缓存拿

所以大量频繁被使用的数据想着放进寄存器中

signed

有符号的 正数和负数

unsigned

无符号的

static

静态的

union

联合体

volatile

C语言暂时不讲

注意

define

include

都不是关键字,是预处理指令

typedef

类型重命名

typedef unsigned int u_int;

int main()

{

   unsigned int num = 100;

   u_int num2 = 100;

   return 0;

}

以上num和num2是一模一样的

张三 — 小三

一样的朋友

static

静态的

static修饰局部变量 static修饰全局变量 static修饰函数

void test()

{

   int a = 1;

   a++;

   printf("%d", a);

}

int main()

{

   int i = 0;

   while (i < 10)

  {

       test();

       i++;

  }

   return 0;

}

输出结果为

2222222222

那我们用static修饰一下

void test()

{

   static int a = 1;

   a++;

   printf("%d", a);

}

int main()

{

   int i = 0;

   while (i < 10)

  {

       test();

       i++;

  }

   return 0;

}

输出结果为

234567891011

出函数时a没有被销毁,生命周期变长了

static可以改变局部变量的声明周期,本质上是改变了变量的存储类型

内存分为

栈区 存局部变量 函数参数 临时的内存 堆区 动态内存分配!! 静态区 全局变量 static修饰的静态变量

a由栈区变为静态区,所以生命周期延长

全局变量在整个工程都可用

文件1

#define _CRT_SECURE_NO_WARNINGS 1

int g_val = 2024;

//全局变量

文件2

//声明

extern int g_val;

int main()

{

   printf("%d", g_val);

   return 0;

}

文件2运行结果

2024

但是

当我们使用static修饰后

#define _CRT_SECURE_NO_WARNINGS 1

static int g_val = 2024;

//全局变量

上面的文件2会报错

无法解析的外部符号

static修饰全局变量使得全局变量只能在自己的源文件(,c)内部可以使用,其他源文件不可用!!!

全局变量

全局变量可以在其他源文件内部可以被使用,是因为源文件具有外部链接属性,但是被static修饰之后就变成了内部链接属性,其他源文件就不能链接到这个静态的全局变量了

修饰函数

文件1

int Add(int x, int y)

{

return x + y;

}

文件2

//声明函数

extern int Add(int, int);

int main()

{

   int a = 10;

   int b = 20;

   int sum = Add(a, b);

   printf("sun = %d\n",sum);

   return 0;

}

文件2运行结果

sum = 30

但是如果我们用static修饰一下函数

文件1

static int Add(int x, int y)

{

return x + y;

}

文件2运行就会报错

错误信息

无法解析的外部符号

所以static修饰使得函数只能在自己所在的源文件内部使用,不能在其他源文件内使用

本质上,static是将函数的外部链接属性变为内部链接属性(和static修饰全局变量一样!!!)

#define 定义常量和宏

define是一个预处理指令

define定义符号 define MAX = 1000; difine定义宏 #define ADD(X,Y) X+Y

int main

{

   printf("%d",4*ADD(2,3));

   return 0;

} 结果为11 为什么呢 define定义宏是替换 4*ADD(2,3)会被换成4X2+3,而不是4X(2+3) 正确写法应该是这样的 #define ADD(X,Y) ((X)+(Y))

int main

{

   printf("%d",4*ADD(2,3));

   return 0;

} 运行结果为 20 后面会详细讲一下这个!!!

优惠劵

J.Pei

关注

关注

7

点赞

6

收藏

觉得还不错?

一键收藏

打赏

知道了

0

评论

初识C语言—操作符,常见关键字,#define 定义常量和宏

define是一个预处理指令define定义符号difine定义宏​int mainreturn 0;结果为11为什么呢define定义宏是替换4*ADD(2,3)会被换成4X2+3,而不是4X(2+3)正确写法应该是这样的​int mainreturn 0;运行结果为20后面会详细讲一下这个!!!

复制链接

扫一扫

参与评论

您还未登录,请先

登录

后发表或查看评论

J.Pei

CSDN认证博客专家

CSDN认证企业博客

码龄1年

郑州轻工业大学

23

原创

152万+

周排名

29万+

总排名

8087

访问

等级

383

积分

114

粉丝

153

获赞

6

评论

114

收藏

私信

关注

热门文章

鸿蒙笔记1

954

初识C语言—数据类型

898

C语言分支和循环语句—分支语句if、else、switch

611

初识C语言—字符串、转义字符、注释

801

初识C语言—选择语句,循环,函数,操作符

596

最新评论

初识C语言—初识C语言

J.Pei:

才发现CSDN可以用markdown格式来写笔记,前面都是直接复制粘贴的,我就不再一篇一篇重新去发前面的文章了,后面会更加注重SCDN的格式的,抱歉大家

C语言分支和循环语句—分支语句if、else、switch

CSDN-Ada助手:

恭喜用户写了第17篇博客,标题为“C语言分支和循环语句—分支语句if、else、switch”,内容涵盖了C语言中重要的分支语句。希望用户能继续保持创作的热情和努力,为读者带来更多有价值的内容。在下一篇博客中,建议可以深入探讨C语言中的循环语句,如for、while等,让读者更全面地了解C语言的基础知识。期待您的精彩分享!愿您的博客越写越好!

C语言分支和循环语句—while

CSDN-Ada助手:

恭喜用户写了第18篇博客,标题为:“C语言分支和循环语句—while”,内容涉及C语言中的重要知识点,非常有参考价值。希望用户能够继续保持创作的热情和努力,不断提升自己的写作水平和深度,可以考虑拓展其他编程语言的相关主题,为读者呈现更丰富多彩的内容。期待用户更多精彩的作品!

初识C语言—结构体

m0_74774849:

博主头像是本人

初识C语言—结构体

CSDN-Ada助手:

C 技能树或许可以帮到你:https://edu.csdn.net/skill/c?utm_source=AI_act_c

您愿意向朋友推荐“博客详情页”吗?

强烈不推荐

不推荐

一般般

推荐

强烈推荐

提交

最新文章

C语言实战—猜数字游戏(涉及循环和少部分函数内容)

快速了解—IEEE754标准32位浮点数的转换

初识C语言—初识C语言

2024年14篇

2023年9篇

目录

目录

最新文章

C语言实战—猜数字游戏(涉及循环和少部分函数内容)

快速了解—IEEE754标准32位浮点数的转换

初识C语言—初识C语言

2024年14篇

2023年9篇

目录

评论

被折叠的  条评论

为什么被折叠?

到【灌水乐园】发言

查看更多评论

添加红包

祝福语

请填写红包祝福语或标题

红包数量

红包个数最小为10个

红包总金额

红包金额最低5元

余额支付

当前余额3.43元

前往充值 >

需支付:10.00元

取消

确定

下一步

知道了

成就一亿技术人!

领取后你会自动成为博主和红包主的粉丝

规则

hope_wisdom 发出的红包

打赏作者

J.Pei

你的鼓励将是我创作的最大动力

¥1

¥2

¥4

¥6

¥10

¥20

扫码支付:¥1

获取中

扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元

使用余额支付

点击重新获取

扫码支付

钱包余额

0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

C语言丨区别 typedef与#define的用法,一文搞懂关键字typedef - 知乎

C语言丨区别 typedef与#define的用法,一文搞懂关键字typedef - 知乎首发于C语言切换模式写文章登录/注册C语言丨区别 typedef与#define的用法,一文搞懂关键字typedef沐歌爱编程为框架而生,为架构而死,为编程奋斗一辈子。在C语言中有一个typedef关键字,其用来定义用户自定义类型。当然,并不是真的创造了一种数据类型,而是给已有的或者符合型的以及复杂的数据类型取一个我们自己更容易理解的别名。总之,可以使用typedef关键字定义一个我们自己的类型名称。它本身是一种存储类的关键字,与auto、extern、mutable、staTIc、register等关键字不能出现在同一个表达式中。那么,究竟如何定义,又有哪些情况下可已使用呢?接下来我们就对它的几种用法进行说明:C语言中typedef的用法1.基本数据类型定义 例如:typedef unsigned char uchar  描述:uchar等价于unsigned char类型定义 uchar c声明等于unsigned char c声明2.数组类型定义  例如: typedef int array[2];  描述: array等价于 int [2]定义; array a声明等价于int a[2]声明  扩展: typedef int array[M][N];  描述: array等价于 int [M][N]定义; array a声明等价于int a[M][N]声明3.指针类型定义  例如: typedef int *pointer;  描述: pointer等价于 int *定义;pointer p声明等价于int *a声明  例如: typedef int *pointer[M];  描述: pointer等价于 int *[M]定义 pointer p声明等价于int *a[M]声明4.函数地址说明  描述:C把函数名字当做函数的首地址来对待,我们可以使用最简单的方法得到函数地址  例如: 函数:int func(void); unsigned long funcAddr=(unsigned long)func, funcAddr的值是func函数的首地址5.函数声明  例如: typedef int func(void); func等价于 int (void)类型函数  描述1: func f声明等价于 int f(void)声明,用于文件的函数声明  描述2: func *pf声明等价于 int (*pf)(void)声明,用于函数指针的生命,见下一条6.函数指针  例如: typedef int (*func)(void)  描述: func等价于int (*)(void)类型  func pf等价于int (*pf)(void)声明,pf是一个函数指针变量typedef关键字与#define宏定义的区别#define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同: 1.从功能范围上讲,Typedef用来定义类型的别名,这些类型不只包含内部类型(int,char等),还包括自定义类型(如struct),可以起到使类型易于记忆的功能。它还有另外一个重要的用途,那就是定义机器无关的类型 。#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。typedef主要是为已存在的关键字或类型及其组合取一个我们容易识别的别名。在这一点上#define也可实现,但初次之外#define还有很多其它用处,如果愿意你可以使用它定义任何代码,这时typedef所不具备的。 2.从执行时间上讲,对于#define定义的宏,其在预处理阶段就会被替换。而typedef定义的类型会在编译时处理。3.从作用于上来讲,一般来说#define定义的宏没有作用域的限制,只要在使用前有定义就可以了。而typedef定义的别名是有作用域的。4.从实现效果来讲,我们使用typedef定义一个指针类型,然后使用该类型可以同时声明对各变量,而#define却不是这样的。如typedef (int*) pType;可以使用pType a,b;这里a和b都是指向整数的指针变量。但我们同样定义#define pType int*,若使用pType a,b;定义a和b,则a是指向整数的指针变量,而b不是。总结:结合上文,不难看出,在对数据类型名进行自定义时,采用typedef更为保险,当然也非一成不变的规律,主要是理解二者的区别,依情况选用。识别typedef的方法  a)、第一步,使用已知的类型定义替代typdef后面的名称,直到只剩下一个名字不识别为正确;  b)、第二步,未知名字为定义类型,类型为取出名称和typedef的所有部分;  c)、第三步,定义一个变量时,变量类型等价于把变量替代未知名字的位置所得到的类型。最后,不管你是转行也好,初学也罢,进阶也可,如果你想学编程成为一名优秀的程序员~【值得加入】我的C语言C++学习企鹅圈子学习交流,技术探讨...还有超多源码素材等学习资料,零基础的视频也超棒~编程学习书籍:编程学习视频:发布于 2021-02-04 13:46数据类型C 语言入门C语言关键字​赞同 11​​添加评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录

C语言宏#define(精通详解) - 知乎

C语言宏#define(精通详解) - 知乎切换模式写文章登录/注册C语言宏#define(精通详解)程序员今日话题​关注我,天天分享C/C++开发技术干货!宏定义又称为宏替换、宏代换,简称“宏”,是C提供的三种预处理功能①的其中一种。其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率②。1. #define命令#define命令是C语言中的一个宏定义命令,它用来讲一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。该命令有两种格式:一种是简单的宏定义(不带参数的宏定义),另一种是带参数的宏定义。(1) 简单的宏定义 格式:#define <宏名/标识符> <字符串> eg:#define PI 3.1415926 说明: ①宏名一般用大写 ②宏定义末尾不加分好; ③可以用#undef命令终止宏定义的作用域 ④宏定义可以嵌套 ⑤字符串“”中永远不包含宏 ⑥宏替换在编译前进行,不分配内存,变量定义分配内存,函数调用在编译后程序运行时进行,并且分配内存 ⑦预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查 ⑧使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义 (2) 带参数的宏定义(除了一般的字符串替换,还要做参数代换)格式:#define <宏名>(<参数表>) <字符串>eg:#define S(a,b) a*b area=S(3,2);第一步被换为area=a*b;第二步换为area=3*2; 一个标识符被宏定义后,该标识符便是一个宏名。这时,在程序中出现的是宏名,在该程序被编译前,先将宏名用被定义的字符串替换,这称为宏替换,替换后才进行编译,宏替换是简单的替换。说明:①实参如果是表达式容易出问题 #define S(r) r*r area=S(a+b);第一步换为area=r*r;第二步换成area=a+b*a+b; 当定义为#define S(r)((r)*(r))时area=((a+b)*(a+b))②宏名和参数的括号间不能有空格 ③宏替换之作替换不做计算,不做表达式求解 ④宏的哑实结合不存在类型,也没有类型转换 ⑤宏展开不占用运行时间,只占用编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值)2. 宏定义易错点示例总结#define 第一位置 第二位置(1)“”内的东西不会被宏替换 #define NAMEzhang 程序中有"NAME"则,它会不会被替换呢? 答:否(2)宏定义前面的那个必须是合法的用户标识符(可以使关键字) #define 0x abcd 可以吗?也就是说,可不可以用把标识符的字母替换成别的东西? 答:否(3)第二位置如果有字符串,必须“”配对 #define NAME "zhang 这个可以吗? 答:否(4)只替换与第一位置完全相同的标识符 #define NAME "zhangyuncong" 程序中有上面的宏定义,并且,程序里有句:NAMELIST这样,会 不会被替换成"zhangyuncong"LIST 答:否(5)带参数宏的一般用法 例如: ①#define MAX(a,b) ((a)>(b)?(a):(b)) 则遇到MAX(1+2,value)则会把它替换成: ((1+2)>(value)?(1+2):(value)) ②#define FUN(a) "a" 则,输入FUN(345)会被替换成什么? 其实,如果这么写,无论宏的实参是什么,都不会影响其被替换成 "a"。也就是说,""内的字符不被当成形参,即使它和一模一样。 ③#define N 2+2 void main() { int a=N*N; printf(“%d”,a); }出现问题:在此程序中存在着宏定义命令,宏N代表的字符串是2+2,在程序中有对宏N的使用,一般同学在读该程序时,容易产生的问题是先求解N为 2+2=4,然后在程序中计算a时使用乘法,即N*N=4*4=16,其实该题的结果为8,为什么结果有这么大的偏差? 问题解析:如1节所述,宏展开是在预处理阶段完成的,这个阶段把替换文本只是看作一个字符串,并不会有任何的计算发生,在展开时是在宏N出现的地方 只是简单地使用串2+2来代替N,并不会增添任何的符号,所以对该程序展开后的结果是a=2+2*2+2,计算后=8,这就是宏替换的实质,如何写程序才 能完成结果为16的运算呢? 解决办法:将宏定义写成如下形式 #define N (2+2) 这样就可替换成(2+2)*(2+2)=16 ④#define area(x) x*xvoid main() { int y=area(2+2); printf(“%d”,y); }按理说给的参数是2+2,所得的结果应该为4*4=16,但是错了,因为该程序的实际结果为8,仍然是没能遵循纯粹的简单替换的规则,又是先计算再替换 了,在这道程序里,2+2即为area宏中的参数,应该由它来替换宏定义中的x,即替换成2+2*2+2=8了。那如果遵循(1)中的解决办法,把2+2 括起来,即把宏体中的x括起来,是否可以呢?#define area(x) (x)*(x),对于area(2+2),替换为(2+2)*(2+2)=16,可以解决,但是对于area(2+2)/area(2+2)又会怎么样呢,有的学生一看到这道题马上给出结果,因为分子分母一样,又错了,还是忘了遵循先替换再计算的规则了,这道题替换后会变为(2+2)*(2+2)/(2+2)*(2+2)即4*4/4*4按照乘除运算规则,结果为16/4*4=4*4=16,那应该怎么呢?解决方法是在整个 宏体上再加一个括号,即#definearea(x) ((x)*(x)),不要觉得这没必要,没有它,是不行的。 要想能够真正使用好宏定义,那么在读别人的程序时,一定要记住先将程序中对宏的使用全部替换成它所代表的字符串,不要自作主张地添加任何其他符号,完全展开后再进行相应的计算,就不会写错运行结果。如果是自己编程使用宏替换,则在使用简单宏定义时,当字符串中不只一个符号时,加上括号表现出优先级,如果是 带参数的宏定义,则要给宏体中的每个参数加上括号,并在整个宏体上再加一个括号。⑤多行宏定义#define doit (m,n) for(inti=0;i<(n);++i) { m+=i; }3. 宏定义其他冷门、重点知识#define Conn(x,y) x##y #define ToChar(x) #@x #define ToString(x) #xx##y表示什么?表示x连接y,举例说:int n = Conn(123,456); 结果就是n=123456; char* str = Conn("asdf","adf")结果就是 str = "asdfadf";#@x,其实就是给x加上单引号,结果返回是一个constchar。举例说: char a = ToChar(1);结果就是a='1'; 做个越界试验char a = ToChar(123);结果是a='3'; 但是如果你的参数超过四个字符,编译器就给给你报错了!error C2015:too many characters in constant :P #x是给x加双引号 char* str = ToString(123132);就成了str="123132";如果有#define FUN(a,b) vo##a##b()那么FUN(idma,in)会被替换成void main()附录:① 预处理功能:(1)文件包含:可以把源程序中的#define扩展为文件正文,即把包含的.h文件找到并展开到#include所在处。(2)条件编译:预处理器根据#if和#ifdef等编译命令及其后的条件,把源程序中的某些部分包含进来或排除在外,通常把排除在外的语句转换成空行。(3)宏展开:预处理器将源程序文件中出现的对宏的引用展开成相应的宏定义,经过预处理器处理的源程序与之前的源程序有所不同,在这个阶段所进行的工作只是纯粹的替换和展开,没有任何计算功能。②使用带参数的宏定义可完成函数调用的功能,又能减少系统开销,提高运行效率。正如C语言中所讲,函数的使用可以使程序更加模块化,便于组织,而且可重复利用,但在发生函数调用时,需要保留调用函数的现场,以便子函数执行结束后能返回继续执行,同样在子函数执行完后要恢复调用函数的现场,这都需要一定的时间,如果子函数执行的操作比较多,这种转换时间开销可以忽略,但如果子函数完成的功能比较少,甚至只完成一点操作,如一个乘法语句的操作,则这部分转换开销就相对较大了,但使用带参数的宏定义就不会出现这个问题,因为它是在预处理阶段即进行了宏展开,在执行时不需要转换,即在当地执行。宏定义可完成简单的操作,但复杂的操作还是要由函数调用来完成,而且宏定义所占用的目标代码空间相对较大。所以在使用时要依据具体情况来决定是否使用宏定义。编辑于 2023-11-23 10:39・IP 属地湖南C / C++C(编程语言)C 语言入门​赞同 111​​18 条评论​分享​喜欢​收藏​申请

C语言define关键字全解析_c语言的define关键字-CSDN博客

>

C语言define关键字全解析_c语言的define关键字-CSDN博客

C语言define关键字全解析

最新推荐文章于 2024-03-07 08:37:22 发布

XingleiGao

最新推荐文章于 2024-03-07 08:37:22 发布

阅读量1.4k

收藏

14

点赞数

18

分类专栏:

c语言学习记录

文章标签:

c语言

算法

生活

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/qq_17593855/article/details/123973395

版权

c语言学习记录

专栏收录该内容

4 篇文章

3 订阅

订阅专栏

作者简介:一个走在前行路上的人 ✨联系方式:2201891280(QQ) ⏳全文大约阅读时间: 60min

☘前言☘

偷个图,如果用上面的方式写代码,中文编码指日可待有没有?哈哈哈哈 在工程代码中,头文件的最开始就能看到一大片#define,今天我们就看一下define这个关键词究竟是怎么用的。这些知识主要来源于博主最近的实习经历和自己写代码的习惯提炼出来哦。

1.防止重复包含

不知道小伙伴们有没有发现我们就算再我们的c文件里面写了两次#include 也没有提示我们重复包含,但是自己写一个头文件的时候就会提示这个问题。 其实我们看看标准库文件都可以看到一些有趣的应用

#ifnodef __TEST__

#define __TEST__

...

代码段 头文件 blabla

...

#endif

这个的作用就是判断是否定义了一个宏,未定义就进行定义并进行相关变量结构体之类的定义,定义的话就会跳过这部分,可以防止重复定义。 同时这个思维也可以用于debug和正式版的切换,这个等下再说。

2.定义常量

其实这个是我们平常最常见的定义方式了,大家应该都会用吧???是吧是吧?但是呢,有坑。。。。

#define PI 3 + 1

printf("%d",10*PI);

我们得到的结果就是31,因为define就是简单的替换,那么后果就是替换成了10*3+1,所以写宏定义的时候建议统统加上括号,防止出错。 所以上面的就是

#define PI (3+1);

printf("%d",10*PI);

就正常啦。

️3.定义函数

宏定义可以作为一些函数来使用,我举几个例子

#define MAX(a,b) ((a)>(b) ? (a) : (b))

这个就是一个求最大值的函数,可以看到全加了括号,就是为了防止上面定义常量出现的问题。

#define SWAP(a,b) do{\

int t = a;\

a = b;

b = t;

}while(0);

就可以实现a、b的交换,可以学到一个小知识就是define可以换行只要加上\,同样的思路也可以用在printf中哟。

const double eps = 1e-8;

const double pi = acos(-1.0);

#define Equ(a, b) ((fabs((a) - (b))) < (eps))

#define More(a, b) (((a) - (b)) > (eps))

#define Less(a, b) (((a) - (b)) < (eps))

#define MoreEqu(a, b) (((a) - (b)) > (-eps))

#define LessEqu(a, b) (((a) - (b)) > (eps))

结合比较函数,我们可以写一些浮点数的比较啦扒拉扒拉,感兴趣可以看看我另外一篇文章。1.3 浮点数的比较

️4.#、#@和##

#define TOSTRING(a) #a

#define CONNECT(a,b) a##b

#define TOCHAR(a) #@a //Microsoft Specific

其实看完上面的代码就很简单了#代表的就是将a变成一个字符串,不过需要注意的是这个返回的是一个指针,也可以说字符串数组,whaterver。 然后##有点类似于strcat会将两个连接到一起返回。 #@用于返回一个字符,有人看到我写的Microsoft Specific了么,这玩意微软专属。。。。。所以在linux下的话我看到有两种写法可以实现类似的功能。

#define TOCHAR(a) #a[0]

#define TOCHAR(a) *#a

其实看一眼都是懂得,就是取出第一个元素来变化,有个小点不知道大家有没有发现其实第一行的结合顺序是先#a然后再[0]的,这样才能取出第一个元素。而第二个就是直接解引用了。

5.一些参数

上班第一天的代码给我看傻了

#define DEBUG

#ifdef DEBUG

#define APP_PRINT(...) printf(__VA_ARGS__)

#else

#define APP_PRINT(...)

#endif

这种写法就是为了控制debug版本和正式版本的,其中__VA_ARGS__就是...匹配到的内容,这样就可以直接控制是否输出调试信息,简直牛犇!!!但是注意这个只支持再后面书写如果书写a...b是错误的,...之后不能再加任何信息了,听别人说的,我试了,是真的0.0,只能接括号

6.一些预定义的宏

宏名称功能LINE正在编译的文件的行号FILE正在编译的文件的名字DATE编译时刻的日期字符串TIME编译时刻的时间字符串STDC判断该程序是否为标准的c程序

写在最后

今天就写到这里了,如果大家觉得对你有帮助的话还希望大家动动手指给个三连0.0 你的支持是我前进最大的动力。

优惠劵

XingleiGao

关注

关注

18

点赞

14

收藏

觉得还不错?

一键收藏

打赏

知道了

12

评论

C语言define关键字全解析

作者简介:一个走在前行路上的人✨联系方式:2201891280(QQ)⏳全文大约阅读时间: 60min☘前言☘偷个图,如果用上面的方式写代码,中文编码指日可待有没有?哈哈哈哈在工程代码中,头文件的最开始就能看到一大片#define,今天我们就看一下define这个关键词究竟是怎么用的。这些知识主要来源于博主最近的实习经历和自己写代码的习惯提炼出来哦。1.防止重复包含不知道小伙伴们有没有发现我们就算再我们的c文件里面写了两次#include <stdio.h>也没有提..

复制链接

扫一扫

专栏目录

13. C语言中的关键字解析.docx

07-03

在学习C语言和C++过程中,我们接触了许多的关键字,下边我们再来回顾一下使用频率比较高的几个关键字:#define(宏定义)、static(静态变量)、const(只读变量)volatile(直接从内存读数据)、typedef

1. C语言#define关键字

Xucc_x的博客

03-26

8467

  #define 关键字有两个作用,一个是定义标识符,第二个是定义宏。

1. 定义标识符

//#define name stuff

#define MYINT int

  建议不要在define定义的标识符里加分号。

2. 定义宏

#define 机制有一个规定,允许把参数替换到文本中,这种实现通常叫做宏或定义宏。

//#define name...

12 条评论

您还未登录,请先

登录

后发表或查看评论

extern、static修饰变量的使用及define和const区别

10-27

extern、static修饰变量的使用及define和const区别可结合博客http://blog.csdn.net/error/404.html?from=http%3a%2f%2fblog.csdn.net%2faiyang10%2farticle%2fdetails%2f49448591理解

【C/C++笔记】之关键词#define的总结

醉逍遥的博客

03-02

407

今天看了几篇关于#define关键字的博客,然后统一归纳总结,整理了一下#define的用法,与大家共享!1.简单的define定义 (定义常量)

#define MAXTIME 1000

一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写

if(i

编译器在处理这个代码之前会对MAXTIME进行处理替换为1000。

这...

C语言 define 关键字

书山有路勤为径

11-16

3080

1)取出两个数值中的最小值

#define MIN(A,B) (((A)>(B))? (B):(A))

2)用宏定义实现一个32 int类型变量 取绝对值

#define ABS(n) (((unsigned int)n>>31 == 0x1) ? (-n):(n))

#define ABS2(n) ((n ^ (n >> 31)) - (n >> 3...

C语言初阶(五) -关键字、#define

分享简单技术,记录点滴成长

04-25

463

关键字

#define

1. 常见关键字

1.1 表格

char

字符型

auto

default

int

整型

extern

break

跳出所在的循环或语句块

float

单精度浮点型

if

continue

跳过本次循环

double

双精度浮点型

else

static

修饰变量或函数使之成为静态

short

短整型

while

rigister

long

长整型

do

typedef

为类型重命名

long long

更长的整型

for

..

初识C语言 4 —关键字、#define定义常量和宏(入门基础篇)

weixin_68839469的博客

05-02

1369

打好基础,从我做起

【define】你知道C语言中define的作用吗?

m0_67077469的博客

07-23

8190

C语言中define的作用

#define 的换行问题

weixin_34007291的博客

06-07

1470

#define + <内容>

#define默认不是以 ';' 结束,而是以换行结束。

因此,#define后面的内容如果太长,一行写不下,必须在行末尾加 '\' ,而且'\' 前面不能有空格

正确格式如:

#define CHKADDRESS(_saddr_)\

{\

u_char* p = (char *) &(_saddr_);\

if(...

C语言之#define用法入门详解

热门推荐

sunnyoldboy博客

11-16

3万+

在C语言中,常量是使用频率很高的一个量。常量是指在程序运行过程中,其值不能被改变的量。常量常使用#define来定义。

使用#define定义的常量也称为符号常量,可以提高程序的运行效率。

C语言中的内联函数(inline)与宏定义(#define)详细解析

01-20

先简明扼要,说下关键:...如同 #define 宏(但并不等同,原因见下文),内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。二、 内联函数是如何在安全和速度上取得折

如何解决C语言,函数名与宏冲突

01-20

您可能感兴趣的文章:详解C语言中的#define宏定义命令用法简单讲解C语言中宏的定义与使用如何在C语言的宏中使用类型关键字C语言中的内联函数(inline)与宏定义(#define)详细解析C语言中宏定义使用的小细节C语言宏定义...

C语言解析教程(原书第4版)(美) 凯利.pdf

07-05

2.4 关键字 2.5 标识符 2.6 常量 2.7 字符串常量 2.8 操作符和标点符号 2.9 操作符的优先级和结合性 2.10 增值操作符和减值操作符 2.11 赋值操作符 2.12 例子:计算2的乘方 2.13 c系统 2.13.1 预处理器 2.13.2 标准...

C语言深度揭秘

04-12

第一章 关键字...............9 1.1,最宽恒大量的关键字----auto................................11 1.2,最快的关键字---- register..................................... 11 1.2.1,皇帝身边的小太监----寄存器...

C语言从入门到精通 第四章(数据的输入和输出)

Zevalin的博客

03-04

1027

(1)从前面的程序可以看到,一个能实现一定功能的程序基本都包含输入输出,至少没有输出的程序是没有任何意义的。(2)所谓输入输出是以计算机为主体而言的,从计算机向输出设备(如显示器、打印机)输出数据的过程称为输出,从输入设备(如键盘、光盘、扫描仪)向计算机输入数据的过程称为输入。

代码随想录算法训练营(动态规划10,11 ,12 股票问题)| 121. 买卖股票的最佳时机 & 122.买卖股票的最佳时机II

he979731102的博客

03-04

514

动态规划10,11, 12 股票问题)| 121. 买卖股票的最佳时机 & 122.买卖股票的最佳时机II

LeetCode27: 移除元素

最新发布

m0_50127633的博客

03-07

378

解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。输入:nums = [3,2,2,3], val = 3。输出:2, nums = [2,2]

96. 不同的二叉搜索树

weixin_45256307的博客

03-06

527

96. 不同的二叉搜索树

力扣404 左叶子之和 Java版本

m0_47066863的博客

03-05

409

这个问题使用后序遍历和层序遍历都是可以的,只需要在遍历的过程中判断一下当前节点的左孩子节点是否是左叶子节点。如果是的话就加起来。解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24。输入: root = [3,9,20,null,null,15,7]给定二叉树的根节点 root ,返回所有左叶子之和。节点数在 [1, 1000] 范围内。输入: root = [1]下面附上后序遍历的递归解法。

用c语言写解析dbc的程序

05-25

DBC(Databus Message Description)是一种用于描述CAN总线消息的格式,其文件通常以 .dbc 扩展名结尾。下面是一个简单的C语言程序,可以解析DBC文件并在控制台上输出消息的相关信息:

```c

#include

#include

#include

#define LINE_MAX_LEN 1024 // 文件读取时每行的最大长度

typedef struct {

int id; // 消息ID

int dlc; // 数据长度码

char name[64]; // 消息名称

} Msg;

int main(int argc, char *argv[]) {

if (argc < 2) {

printf("Usage: %s dbc_file\n", argv[0]);

return 0;

}

FILE *fp = fopen(argv[1], "r");

if (!fp) {

perror("Failed to open file");

return -1;

}

char line[LINE_MAX_LEN];

char *token;

Msg msg;

memset(&msg, 0, sizeof(Msg));

while (fgets(line, LINE_MAX_LEN, fp)) {

// 去除行末的空格和换行符

line[strcspn(line, "\r\n")] = '\0';

token = strtok(line, " ");

if (!strcmp(token, "BO_")) { // Message definition

token = strtok(NULL, " ");

msg.id = atoi(token);

token = strtok(NULL, " ");

token = strtok(NULL, " ");

strncpy(msg.name, token, sizeof(msg.name)-1);

printf("ID: %d, Name: %s\n", msg.id, msg.name);

} else if (!strcmp(token, "SG_")) { // Signal definition

token = strtok(NULL, " ");

token = strtok(NULL, " ");

int start_bit = atoi(token);

token = strtok(NULL, "|");

int bit_len = atoi(token);

printf("Start bit: %d, Bit length: %d\n", start_bit, bit_len);

}

}

fclose(fp);

return 0;

}

```

该程序的主要思路是读取DBC文件,逐行解析文件中的内容,并输出消息的相关信息。使用 strtok 函数对每行进行分割,然后根据不同的关键字(BO_ 或 SG_)进行不同的处理。在实际的开发中,需要根据具体的需求对程序进行修改和优化。

“相关推荐”对你有帮助么?

非常没帮助

没帮助

一般

有帮助

非常有帮助

提交

XingleiGao

博客等级

码龄10年

全栈领域新星创作者

202

原创

821

点赞

1027

收藏

3015

粉丝

关注

私信

热门文章

室友收了个房租,搞懂了C语言的指针

10212

全球最大的自主物联网系统——鸿蒙?不,是小米vela

5769

【解题报告】《LeetCode零基础指南》(第四讲) 一维数组

5730

【解题报告】《LeetCode零基础指南》(第三讲) 循环

5228

【从零开始的嵌入式生活】数据结构2——线性表及顺序表

4742

分类专栏

RISC-V体系结构学习

1篇

嵌入式笔记

34篇

每日一题

39篇

ARM64体系结构

1篇

UEFI学习报告

1篇

机械狗相关

1篇

《算法笔记》记录

10篇

经验杂谈

1篇

九日集训

11篇

《算法零基础100讲》解题报告

47篇

XingleiGao的日常

4篇

c语言学习记录

4篇

python学习记录

2篇

[解题报告]《C语言入门100例》

23篇

算法笔记刷题

14篇

刷题计划

7篇

最新评论

VSCODE+QEMU+WSL调试RISCV代码(SBI、kernel)

XingleiGao:

qemu肯定打开的,只不过是在task.json里面我写了make run里面去实现的,在run的时候其实加了-s参数已经启了gdb服务。lunch.json里面用gdb远程去连接的。

VSCODE+QEMU+WSL调试RISCV代码(SBI、kernel)

浅木_log:

您好,请问调试的时候Linux的qemu服务需要打开吗?gdb服务呢?

【从零开始的python生活①】手撕爬虫扒一扒力扣的用户刷题数据

子虫517:

手撕爬虫是什么黑话啊

【C语言有什么用?①】从零开始撸一个用户态模拟文件系统

CSDN-Ada助手:

多亏了你这篇博客, 解决了问题: https://ask.csdn.net/questions/7994773, 请多输出高质量博客, 帮助更多的人

1.UEFI环境搭建

Mechatronics_MTA:

您好,请查看我的消息

您愿意向朋友推荐“博客详情页”吗?

强烈不推荐

不推荐

一般般

推荐

强烈推荐

提交

最新文章

VSCODE+QEMU+WSL调试RISCV代码(SBI、kernel)

一道简单题引发的思考

【我是学生,可以送我么】搭建树莓派4bJTAG调试平台jlink平替版

2023年1篇

2022年92篇

2021年109篇

目录

目录

分类专栏

RISC-V体系结构学习

1篇

嵌入式笔记

34篇

每日一题

39篇

ARM64体系结构

1篇

UEFI学习报告

1篇

机械狗相关

1篇

《算法笔记》记录

10篇

经验杂谈

1篇

九日集训

11篇

《算法零基础100讲》解题报告

47篇

XingleiGao的日常

4篇

c语言学习记录

4篇

python学习记录

2篇

[解题报告]《C语言入门100例》

23篇

算法笔记刷题

14篇

刷题计划

7篇

目录

评论 12

被折叠的  条评论

为什么被折叠?

到【灌水乐园】发言

查看更多评论

添加红包

祝福语

请填写红包祝福语或标题

红包数量

红包个数最小为10个

红包总金额

红包金额最低5元

余额支付

当前余额3.43元

前往充值 >

需支付:10.00元

取消

确定

下一步

知道了

成就一亿技术人!

领取后你会自动成为博主和红包主的粉丝

规则

hope_wisdom 发出的红包

打赏作者

XingleiGao

你的鼓励将是我创作的最大动力

¥1

¥2

¥4

¥6

¥10

¥20

扫码支付:¥1

获取中

扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元

使用余额支付

点击重新获取

扫码支付

钱包余额

0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

C语言#define关键字,条件编译及预定义符号知识详解 - 知乎

C语言#define关键字,条件编译及预定义符号知识详解 - 知乎首发于C语言C++学习切换模式写文章登录/注册C语言#define关键字,条件编译及预定义符号知识详解叶子编程知识分享一.预定义符号C标准定义了如下五个预处理符号在文件输入输出以及输出日志等场合下我们会用到这些预处理符号,比如\+回车 : 续行符,转义字符,后面不能加任何除回车之外的字符,否则会报错二.#define关键字#define有两个作用,一个是定义标识符,第二个是定义宏1.定义标识符不要在define定义的标识符里加分号2.定义宏#define机制包括一个规定,允许把参数替换到文本中,这种实现通常叫做宏或定义宏宏定义永远不要吝啬括号,防止因为优先级的问题导致出现不可思议的后果 宏不能实现递归 宏只文本替换,并不简化计算 字符串中的内容不会发生宏替换3.#和 ##编译器会自动就两个相邻字符串自动连接成一个#:把参数插入到字符串中#a -> “a”##可以把位于它两边的符号拼成一个符号4.宏和函数对比①宏没有类型检查没有类型检查是宏的一大特点(但同时也是不安全的隐患),可以完成很多函数不可能做到的功能②宏没有函数的调用和返回等额外开销,效率更高,但是当逻辑复杂并且代码量巨大时,调用和返回的开销和运算的时间相比微乎其微,可以省略③宏单纯只是文本替换,不能进行调试,很致命④宏可能会使代码长度增长⑤函数的参数如果是一个表达式,会计算出表达式的结果传入参数宏的参数如果是一个表达式,只会文本替换,不会进行计算总结:各有千秋,小代码量使用宏,大代码量使用函数,C++中摈弃宏这一概念,使用内联,基于优缺点,最好不要使用宏.小编推荐一个学C语言/C++的学习裙【 六二七,零一二,四六四 】,无论你是大牛还是小白,是想转行还是想入行都可以来了解一起进步一起学习!裙内有开发工具,很多干货和技术资料分享!5.带有副作用的宏参数不要给宏参数传入带有副作用的参数6.命名约定宏:全部大写函数: 不全部大写例外#undef name //取消宏标识符name的定义三.条件编译1.如果定义了DEBUG,语句执行,反之,不执行2.条件编译3.多分支条件编译3.判断是否被定义4.嵌套指令预处理指令可以进行嵌套四.其它1.头文件的包含2.#error “…”遇到#error便会产生一个编译错误3.strcpy();源字符串必须以’/0’结束,返回目标字符串地址且这个函数不管目标空间是否放得下返回的目标字符串4.assert(条件语句)善用断言,头文件为5.链式反应这次函数的返回值可以作为下一个函数的参数,达到链式反应的效果printf(“%d\n”,strlen(strcpy(p,”hello world!”)));6.常见错误:编译型错误直接看编译器错误提示信息即可 链接型错误函数名,变量名写错,库文件使用错误(第三方库) 运行时错误发布于 2018-03-29 23:32C(编程语言)C / C++C 语言入门​赞同 9​​添加评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录C语言C++学习C语言C++技术交流,快乐学习

#define用法,C语言#define详解

#define用法,C语言#define详解

首页

C语言教程

C++教程

Python教程

Java教程

Linux入门

更多>>

首页 > 编程笔记

#define用法,C语言#define详解

C语言中,可以用 #define 定义一个标识符来表示一个常量。其特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了。

预编译又叫预处理。预编译不是编译,而是编译前的处理,编译器正式开始编译程序之前,会执行一段预处理程序(又称预处理器)专门对程序执行预处理操作。

C语言程序从编写到运行要经过预处理、编译、汇编和链接这 4 个阶段,但大多数人习惯将前 3 个阶段统称为编译阶段,所以才有了“程序要经过编译和链接后才能运行”的说法。关于各个阶段到底做了哪些工作,C语言程序又是怎样一步步转换为可执行程序的,感兴趣的读者请猛击这里了解详情。

用 #define 定义标识符的一般形式为:

#define  标识符  常量   //注意, 最后没有分号

#define 和 #include 一样,也是以“#”开头的。凡是以“#”开头的均为预处理指令,#define也不例外。

#define又称宏定义,标识符为所定义的宏名,简称宏。标识符的命名规则与前面讲的变量的命名规则是一样的。#define 的功能是将标识符定义为其后的常量。一经定义,程序中就可以直接用标识符来表示这个常量。是不是与定义变量类似?但是要区分开!变量名表示的是一个变量,但宏名表示的是一个常量。可以给变量赋值,但绝不能给常量赋值。

宏所表示的常量可以是数字、字符、字符串、表达式。其中最常用的是数字。

那么,程序中什么时候会使用宏定义呢?用宏定义有什么好处呢?我们直接写数字不行吗?为什么要用一个标识符表示数字呢?

宏定义最大的好处是“方便程序的修改”。使用宏定义可以用宏代替一个在程序中经常使用的常量。注意,是“经常”使用的。这样,当需要改变这个常量的值时,就不需要对整个程序一个一个进行修改,只需修改宏定义中的常量即可。且当常量比较长时,使用宏就可以用较短的有意义的标识符来代替它,这样编程的时候就会更方便,不容易出错。因此,宏定义的优点就是方便和易于维护。

那么程序在预编译的时候是怎么处理宏定义的呢?或者说是怎么处理预处理指令的呢?

其实预编译所执行的操作就是简单的“文本”替换。对宏定义而言,预编译的时候会将程序中所有出现“标识符”的地方全部用这个“常量”替换,称为“宏替换”或“宏展开”。替换完了之后再进行正式的编译。所以说当单击“编译”的时候实际上是执行了两个操作,即先预编译,然后才正式编译。#include也是这样的,即在预处理的时候先单纯地用头文件stdio.h中所有的“文本”内容替换程序中#include这一行,然后再进行正式编译。

需要注意的是,预处理指令不是语句,所以后面不能加分号。这是很多新手经常犯的错误。#include 后面也没有加分号。

宏定义 #define 一般都写在函数外面,与 #include 写在一起。当然,写在函数里面也没有语法错误,但通常不那么写。#define 的作用域为自 #define 那一行起到源程序结束。如果要终止其作用域可以使用 #undef 命令,格式为:

#undef  标识符

undef 后面的标识符表示你所要终止的宏。比如前面在程序开头用 define 定义了一个宏 M,它原本的作用范围是一直到程序结束,但如果现在在程序中某个位置加了一句:

#undef M

那么这个宏的作用范围到此就结束了。#undef 用得不多,但大家要了解。

为了将标识符与变量名区别开来,习惯上标识符全部用大写字母表示。宏定义用得最多的地方是在数组中用于指定数组的长度。下面来写一个程序:

# include

# define NUM 5

int main(void)

{

int i, j = NUM;

int a[NUM] = {0};

printf("请输入%d个数:", j);

for (i=0; i

{

scanf("%d", &a[i] );

}

for (i=0; i

{

printf("%d\x20", a[i]);

}

printf("\n");

return 0;

}

输出结果是:

请输入5个数:5 4 3 2 1

5 4 3 2 1

NUM 是定义的宏,它表示的是其后的常量(而不是变量)。此外,程序中用双引号括起来的宏在预处理的时候是不会被宏替换的。因为在 C 语言中,用双引号括起来表示的是字符串。下面再写一个程序看一下:

# include

# define PI 3.14159

int main(void)

{

double r, s;

printf("请输入圆的半径:");

scanf("%lf", &r); //scanf中, double只能用%lf

s = PI * r * r;

printf("s=PI*r^2 = %.6f\n", s); //PI不会被宏替换

return 0;

}

输出结果是:

请输入圆的半径:1

s=PI*r^2 = 3.141590

推荐阅读

C++ copy_n(STL copy_n)算法详解

Java线程的概念:什么是线程?

文本文件和二进制文件到底有什么区别?

C# TextBox:文本框控件

goroutine(Go语言并发)如何使用才更加高效?

第一个多线程程序

Redis HLEN命令行

Redis LREM命令

CSS盒子模型精讲

MySQL字符串类型(超级详细)

精美而实用的网站,分享优质编程教程,帮助有志青年。千锤百炼,只为大作;精益求精,处处斟酌;这种教程,看一眼就倾心。

关于网站 |

联系我们 |

网站地图

Copyright ©2012-2023 biancheng.net

C语言define关键字全解析-阿里云开发者社区

C语言define关键字全解析-阿里云开发者社区

产品解决方案文档与社区权益中心定价云市场合作伙伴支持与服务了解阿里云售前咨询 95187-1 在线服务售后咨询 4008013260 在线服务其他服务 我要建议 我要投诉更多联系方式备案控制台开发者社区首页探索云世界探索云世界云上快速入门,热门云上应用快速查找了解更多问产品动手实践考认证TIANCHI大赛活动广场活动广场丰富的线上&线下活动,深入探索云世界任务中心做任务,得社区积分和周边高校计划让每位学生受益于普惠算力训练营资深技术专家手把手带教话题畅聊无限,分享你的技术见解开发者评测最真实的开发者用云体验乘风者计划让创作激发创新阿里云MVP遇见技术追梦人直播技术交流,直击现场下载下载海量开发者使用工具、手册,免费下载镜像站极速、全面、稳定、安全的开源镜像技术资料开发手册、白皮书、案例集等实战精华插件为开发者定制的Chrome浏览器插件探索云世界新手上云云上应用构建云上数据管理云上探索人工智能云计算弹性计算无影存储网络倚天云原生容器serverless中间件微服务可观测消息队列数据库关系型数据库NoSQL数据库数据仓库数据管理工具PolarDB开源向量数据库热门Modelscope模型即服务弹性计算云原生数据库物联网云效DevOps龙蜥操作系统平头哥钉钉开放平台大数据大数据计算实时数仓Hologres实时计算FlinkE-MapReduceDataWorksElasticsearch机器学习平台PAI智能搜索推荐人工智能机器学习平台PAI视觉智能开放平台智能语音交互自然语言处理多模态模型pythonsdk通用模型开发与运维云效DevOps钉钉宜搭支持服务镜像站码上公益

开发者社区

开发与运维

文章

正文

C语言define关键字全解析

2022-04-20

223

版权

版权声明:

本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《

阿里云开发者社区用户服务协议》和

《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写

侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

简介:

C语言define关键字全解析

游客kyclow5orjnii

目录

热门文章

最新文章

为什么选择阿里云什么是云计算全球基础设施技术领先稳定可靠安全合规分析师报告产品和定价全部产品免费试用产品动态产品定价价格计算器云上成本管理解决方案技术解决方案文档与社区文档开发者社区天池大赛培训与认证权益中心免费试用高校计划企业扶持计划推荐返现计划支持与服务基础服务企业增值服务迁云服务官网公告健康看板信任中心关注阿里云关注阿里云公众号或下载阿里云APP,关注云资讯,随时随地运维管控云服务售前咨询:95187-1售后服务:400-80-13260法律声明及隐私权政策Cookies政策廉正举报安全举报联系我们加入我们阿里巴巴集团淘宝网天猫全球速卖通阿里巴巴国际交易市场1688阿里妈妈飞猪阿里云计算AliOS万网高德UC友盟优酷钉钉支付宝达摩院淘宝海外阿里云盘饿了么© 2009-2024 Aliyun.com 版权所有 增值电信业务经营许可证: 浙B2-20080101 域名注册服务机构许可: 浙D3-20210002 京D3-20220015浙公网安备 33010602009975号浙B2-20080101-4

如何理解C++中的关键字static, const, 以及#define在定义变量时的区别? - 知乎

如何理解C++中的关键字static, const, 以及#define在定义变量时的区别? - 知乎首页知乎知学堂发现等你来答​切换模式登录/注册C++C / C++如何理解C++中的关键字static, const, 以及#define在定义变量时的区别?如题,他们有什么区别和联系呢?使用的时候有哪些需要注意的细节?关注者95被浏览22,545关注问题​写回答​邀请回答​好问题 1​添加评论​分享​5 个回答默认排序Xi Yang知乎说我头像太涩了​ 关注#define和那两个都不一样,它属于宏,是预处理器的一部分。预处理是在编译之前的一道,简单地进行字符串替换。它不按照语言的语法,而是直观自己的语法。你#define里面写的东西会被简单粗暴地塞进去:#define FuckTwice fuck fuck

FuckTwice;

会得到:fuck fuck;编译器会感觉你写了一个变量,名字是fuck,类型是fuck。const是单词constant的简写,字面意思是常数、常量。用于变量修饰,表明这个变量不能被修改;用于指针修饰,表明指针的指向物不能被修改;用于方法修饰,表明这个方法不会对对象造成改变。const int foo = 1;

foo = 2; // compile time error

const int* ptr = &foo;

*ptr = 3 // compile time error

int fuck = 0;

ptr = &fuck; // this is OK

*ptr = 123; // compile time error

struct FooBar

{

int member;

int MyMethod(int value) const

{

member = value; // compile time error

}

};static很讨厌,有三个个完全不同的含义:用在全局变量,表明这个变量在每个编译单元有独自的实例:// foo.h

static int a = 123;// foo.cpp

#include "foo.h"

int foo_func() { return a++; }

// bar.cpp

#include "foo.h"

int bar_func() { return a++; }如果你分别编译foo.cpp和bar.cpp,再把它们链接在一起,全局变量a会有两份,那两个函数会操纵不一样的a实例。用在函数里的局部变量,表明它的生存周期其实是全局变量,但仅在函数内可见:int get_global_id()

{

static int seed = 0;

return seed++;

}每次访问这个函数的时候,会获得不同的int值。那个=0的操作仅在第一次访问时执行,其实是初始化而不是赋值。用在类成员,表明成员或者方法是类的,而不是对象实例的。struct Foo

{

int a = 0;

static int aaa = 0;

static int bbb() { return 123456; }

};每个Foo实例会只含有一个int a。bbb方法通过Foo::bbb()调用。发布于 2015-10-21 13:38​赞同 118​​22 条评论​分享​收藏​喜欢收起​知乎用户UJGhia​ 关注这三个是完全不同的东西其中static用于在类中声明类方法或类变量,或者在函数中声明静态变量(在该函数的多次调用中指向同一内存区域的变量),似乎还有别的类似用处,记不清了。const用于声明常量,就是不可改变的量。而上面的static变量是可以改变的。对常量的改变会导致编译器报错。常量是会在栈上分配空间的。define表面上跟const很像,但实质完全不同。它是一个继承自C的机制,叫做宏。它做的事情是纯粹的字符串替换,而不会分配空间。宏能完成比const复杂得多的工作。虽然在effective C++里貌似不推荐使用宏发布于 2015-04-05 11:26​赞同 4​​添加评论​分享​收藏​喜欢