c语言debug宏如何使用(c++ debug怎么用)

今天给各位分享c语言debug如何使用的知识,其中也会对c++ debug怎么用进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

1、C语言中#if defined(__DEBUG__) # define Msg(msg) printf(“%s\n”, msg) #else # define Msg(msg) #endif2、C语言程序中为什么要使用debug宏3、C语言的宏(macro)是什么?怎样使用宏?

C语言中#if defined(__DEBUG__) # define Msg(msg) printf(“%s\n”, msg) #else # define Msg(msg) #endif

这是C语言的宏定义

#if defined(__DEBUG__) 如果定义了宏 __DEBUG__ 可以在编译选项中加这个宏,也可以在调用代码前用#define命令来定义这个宏,也可以不定义

# define Msg(msg) printf(“%s\n”, msg) 如果定义了宏 __DEBUG__,则遇到Msg(msg) 这样的语句,就会替换成printf(“%s\n”, msg)

#else

# define Msg(msg) 否则,没定义宏__DEBUG__,则遇到Msg(msg) ,就会替换成一个空语句。

#endif

c语言debug宏如何使用(c++ debug怎么用)

C语言程序中为什么要使用debug宏

一个小程序试很多东西,改一会,思路和程序结构和参数设置全变样了,为了便捷地测试一些想要的C语言特性或运行结果,不停的在源程序上加对照组,改功能,相当于版本1、版本2、版本x同体~~~~printf不改怎么能行呢,给我打印个X出来看看对错――X刚才就不存在~!

还有一个不用debug宏的原因就是,某种程度上,debug宏开关的理念和把printf注释掉是一样的(个人理解)。

不过借口归借口,还是写的程序太小了,大一点的工程不用就不现实了,也不够“高大上”,话说回来,频繁改、程序小就是不用的借口了么?

恰巧昨天看了一道C语言面试题,认为至少那个网页给的答案是错的,于是想测试一下,题目如下:

请问下面程序有什么错误?int a[60][250][1000],i,j,k;for(k=0;k=1000;k++)for(j=0;j250;j++)for(i=0;i60;i++)a[i][j][k]=0;答案:把循环语句内外换一下

个人认为:错误关键在于k = 1000的那个等于号――越界了。跟顺序没关系。

==================================================================================================================

另外,即使排除k = 1000造成的数组越界,linux下仍然segmentation fault(core dumped),1000*250*60byte==15000000B,按估算空间没超,不知道为什么,是栈不够?反正我把1000改成100就行了~!

不过,这都是另一个或是另两个话题了,本次是对上边的那个“答案”质疑,想办法证明是错的,主要是为了在过程中引入debug宏。

==================================================================================================================

版本1:贴“答案”给出的方法,只改for循环的顺序:

int a[60][250][1000],i,j,k; for(i = 0;i 60;i++) for(j=0;j 250;j++) for(k = 0;k =1000;k++) a[i][j][k] = 0; for(i= 0;i 60;i++) for(j=0;j 250;j++) for(k = 0;k =1000;k++) printf(“%d/t”,a[i][j][k]);

明显的不行~!

版本2.0:首先,需要把那个k= 1000改成k 1000,来验证我的想法,证明“参考答案”错误。

#includemain(){ inta[60][250][1000],i,j,k; for(k = 0;k 1000;k++) for(j=0;j 250;j++) for(i = 0; i 60;i++) a[i][j][k] = 0; for(i = 0;i 60;i++) for(j=0;j 250;j++) for(k = 0;k 1000;k++) printf(“%d/t”,a[i][j][k]);}

结果segmentation fault(core dumped)了。

版本2.1:小修改。直接猜到了方向,把1000改成100了,这下程序运行正常。

版本3: k 100,赋值语句从0改成i+j+k了,for内层加上大括号,打印也升级为可读性更强的格式~

inta[60][250][100],i,j,k; for(i = 0;i 60;i++) for(j=0;j 250;j++) for(k = 0;k 100;k++){ a[i][j][k] = i+ j + k; printf(“a[%d][%d][%d] = %d/t”,i,j,k,a[i][j][k]); }

这些看起来很自然,但是,如果这些都是在一个源文件内改的,那会有多麻烦,而且原来的还找不回来,可能这里有比较好的一个法子,就是/*注释代码段*/

但是那样依然比较麻烦,开关的灵活性稍差,还有不小心注释错了范围的问题。其实即使有这点问题,也依然能用,但是既然已经这么麻烦了,何不尝试引入宏,养成一个比较有用的好习惯呢?因为这只是小test,正经的程序要大得多。

合体版本:

#include//通过宏激活三个版本,分别是数组越界,数组不越界但是仍然core dump,和一个改小数组的可执行(完成)版本。//#define WRONG_H_//#define K_EQ_1000_H_#define K_EQ_100_H_main(){#ifdef WRONG_H_ inta[60][250][1000],i,j,k; for(i = 0;i 60;i++) for(j=0;j 250;j++) for(k = 0;k = 1000;k++){ a[i][j][k] = i+ j + k; printf(“a[%d][%d][%d] = %d/t”,i,j,k,a[i][j][k]); }#endif#ifdef K_EQ_1000_H_ inta[60][250][1000],i,j,k; for(k = 0;k 1000;k++) for(j=0;j 250;j++) for(i = 0; i 60;i++){ a[i][j][k] = i+ j + k; printf(“a[%d][%d][%d] = %d/t”,i,j,k,a[i][j][k]); }#endif#ifdef K_EQ_100 int a[60][250][100],i,j,k; for(i = 0;i 60;i++) for(j=0;j 250;j++) for(k = 0;k 100;k++){ a[i][j][k] = i + j + k; printf(“a[%d][%d][%d] = %d/t”,i,j,k,a[i][j][k]); }#endif}

虽然是有点作用了,不过真正的debug可能耦合度低一点,代码重复度也应该小,本例中大部分代码重复(也可以只把循环中某一换用#ifdef和#endif括起来)。

既然知道改进方向,何不尝试一下,因为for顺序明显没影响,所以就统一了,降低耦合度么。不过数组定义的k等于1000和100那个没法拆,只能分开算了,我要体现出debug宏相对于注释的优势来。

首先,尝试拆分代码段,只对有区别的语句用宏分类,其次,不同宏之间可以用||来合并。不过还是有问题:不能使用下边这种只有if没有else的形式:

#include#define ORIGINAL_H_//#define K_EQ_1000_H_//#define K_EQ_100_H_#define FINAL_H_main(){#ifdef K_EQ_1000_H_||ORIGINAL_H_ inta[60][250][1000],i,j,k; for(k = 0;k 1000;k++)#endif#ifdef K_EQ_100_H_ || FINAL_H_ inta[60][250][100],i,j,k; for(k = 0;k 100;k++)#endif for(j=0;j 250;j++) for(i = 0; i 60;i++){ a[i][j][k] = i+ j + k; printf(“a[%d][%d][%d] = %d/t”,i,j,k,a[i][j][k]); }}

因为i,j,k等都需要声明定义,它们在#ifdef里边,不能保证一定声明。即使你真开了那个选项,也不被允许(编译器的事儿吧)。

那么折中,为了方便,我选择了相对简化解――“ if 配 else ”,并且把条件砍少了。具体应该怎样做,应该衡量自己的情况定。

include//排除绝对错误的用法和合并不大的改动,最后焦点就在k的大小,完全体是100,测试体是1000(假设目标是找core dumped的原因)//#define K_EQ_1000_H_//#define K_EQ_100_H_main(){#ifdef K_EQ_1000_H_ inta[60][250][1000],i,j,k; for(k = 0;k 1000;k++)#else inta[60][250][100],i,j,k; for(k = 0;k 100;k++)#endif for(j=0;j 250;j++) for(i = 0; i 60;i++){ a[i][j][k] = i+ j + k; printf(“a[%d][%d][%d] = %d/t”,i,j,k,a[i][j][k]); }}

这种方案也不是很完美,如注释所说,我简化了很多问题。不过,如果想把所有的语句和差别都弄上,也可以,不过视觉上会很乱~没有建设性,不做了,如果真想做,因为按句找差异进行拆分的思路已经有了(例如数组的声明和for循环的k部分),把其他所有想要的差异都一句一句拆分,然后给各个宏就完了。一句一句的拆分,比注释有点优越性了吧,如果这种一两句的分化特别多,成百上千行,那一句一句改是要死人的。

现在,把宏都注释掉,想要哪个版本的运行结果,只要取消注释就行了~既能运行错误版本去测试,又能运行“终极形态”完成任务,本例中宏的功能,更形象的说,是一个选择开关,不过,debug宏不就是个开关么?

虽然是比较粗糙的一种使用方式,不是“原装大厂”debug“的用法和教程,但是也算一种思路,更符合我们循序渐进的学习规律――你遇到困难或者效率低,然后解决这个障碍或者提高效率。其实最重要的还是你要在平时找机会引入各种应该掌握的功能,锻炼技巧,保持好习惯

C语言的宏(macro)是什么?怎样使用宏?

#define VERSION—STAMP “1.02″上例中所定义的这种形式的宏通常被称为标识符。在上例中,标识符VERSION_STAMP即代表字符串”1.02″——在编译预处理时,源代码中的每个VERSION_STAMP标识符都将被字符串“1.02”替换掉。以下是另一个宏定义的例子:#define CUBE(x)((x),(x)*(x))上例中定义了一个名为CUBE的宏,它有一个参数x。CUBE宏有自己的宏体,即((x)*(x)*(x))——在编译预处理时,源代码中的每个CUBE(x)宏都将被((x)*(x)*(x))替换掉。使用宏有以下几点好处: (1)在输入源代码时,可省去许多键入操作。(2)因为宏只需定义一次,但可以多次使用,所以使用宏能增强程序的易读性和可靠性。(3)使用宏不需要额外的开销,因为宏所代表的代码只在宏出现的地方展开,因此不会引起程序中的跳转。(4)宏的参数对类型不敏感,因此你不必考虑将何种数据类型传递给宏。需要注意的是,在宏名和括起参数的括号之间绝对不能有空格。此外,为了避免在翻译宏时产生歧义,宏体也应该用括号括起来。例如,象下例中这样定义CUBE宏是不正确的:denne CUBE(x) x * x * x对传递给宏的参数也要小心,例如,一种常见的错误就是将自增变量传递给宏,请看下例:#include stdio. h#include CUBE(x) (x * x * x)void main (void);void main (void){int x, y;x = 5;y = CUBE( + +x);printfC’y is %d\n” . y);}在上例中,y究竟等于多少呢?实际上,y既不等于125(5的立方),也不等于336(6* 7*8),而是等于512。因为变量x被作为参数传递给宏时进行了自增运算,所以上例中的CUBE宏实际上是按以下形式展开的:y = ((++x) * (++x) * (++x));这样,每次引用x时,x都要自增,所以你得到的结果与你预期的结果相差很远,在上例中,由于x被引用了3次,而且又使用了自增运算符,因此,在展开宏的代码时,x实际上为8,你将得到8的立方,而不5的立方。上述错误是比较常见的,作者曾亲眼见过有多年C语言编程经验的人犯这种错误。因为在程序中检查这种错误是非常费劲的,所以你要给予充分的注意。你最好试一下上面的例子,亲眼看一下那个令人惊讶的结果值(512)。宏也可使用一些特殊的运算符,例如字符串化运算符“#”和。连接运算符“##”。“#”运算符能将宏的参数转换为带双引号的字符串,请看下例:define DEBUG_VALUE(v) printf(#v”is equal to %d.\n”,v)你可以在程序中用DEBUG_VALUE宏检查变量的值,请看下例:int x=20;DEBUG_VALUE(x);上述语句将在屏幕上打印”x is equal to 20″。这个例子说明,宏所使用的“#”运算符是一种非常方便的调试工具。“##”运算符的作用是将两个独立的字符串连接成一个字符串。

c语言debug宏如何使用的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于c++ debug怎么用、c语言debug宏如何使用的信息别忘了在本站进行查找喔。

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年4月3日 15:15:24
下一篇 2024年4月3日 15:24:50

相关推荐

  • c语言的汇编版本,c语言 汇编

    学了C语言后想学汇编,请问汇编有分版本么?我应该学习哪一种的? 1、我也是学自动化的,自动化这个专业学的东西很多很杂,汇编语言当然是要学的,我们当时就是学的微机原理这门课。如果你要自学单片机,讲单片机这方面的书都差不多可以的,像《51单片机》这种。 2、有一本书特别适合C的入门,《C Primer Plus(第五版)中文版》,它是目前C的讲解最细最全的,十分…

    2024年5月18日
    3000
  • for是c语言关键字,c语言中for的功能

    C语言For是用户标识符吗,好像小写for才是关键字吧 1、你写错了是小写的for 这个是C语言的关键字,关键字不可以做标识符。因为C语言拿它做循环了。 2、不能把C语言关键字作为用户标识符,例如if ,for, while等.标识符长度是由机器上的编译系统决定的,一般的限制为8字符(注:8字符长度限制是C89标准,C99标准已经扩充长度,其实大部分工业标准…

    2024年5月18日
    4000
  • c语言ctype.h,c语言ctype函数

    C语言判断字符串是不是都是字母 1、isalnum() 用来判断一个字符是否为英文字母或数字,相当于 isalpha(c) || isdigit(c),其原型为:int isalnum(int c);【参数】c 为需要检测的字符。 2、根据ascii码值判断即可。由于数字,大小写字母均分别为连续存储,所以只需要与对应的最大最小值比较即可确定字符类型。代码如下…

    2024年5月18日
    4700
  • 单片机c语言延时计算,单片机c语言延时函数延时时间咋算

    单片机延时1秒如何计算要最详细一点的要过程用C语言 C语言的语句,就要更多。在编写延时函数之前,首先确认一下系统对晶振的分频系数,从而确定每个单周期指令执行所需的时间,一般的单片机都将指令执行周期设置为1us,这样就可以写一个比较接近1秒的延时函数了。 k不一样延时也不一样。而这种靠执行指令延时的程序的延时里昂: 可以通过查看她的反汇编代码来分析得到。 也可…

    2024年5月18日
    3600
  • c语言字符串倒置函数,c语言字符串处理函数

    C语言编程题,求编写一个函数,实现字符串逆置? char p=s;for(i=0;p[i]!=\0;i++);这个地方改下,看你想要用指针还是用数组。 参数string:要颠倒字符次序的字符串返回值String。函数执行成功时返回颠倒字符次序后的字符串,如果发生错误,那么返回空字符串()。 反序字符串,只需要将首尾字符依次调换即可。 编写一个函数,使输入的一…

    2024年5月18日
    3200
  • 找出2到100以内的所有素数c语言,找出1100之间的素数c语言

    用C语言,判断1-100之间有多少个素数,并输出所有素数。 输出1-100以内的素数:同样,也是输出1-100以内的素数,这个构造一个数组,将其所有元素初始化为1,表示素数,这时取x从2开始,到100以内做循环。 题目:判断101-200之间有多少个素数,并输出所有素数。程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此…

    2024年5月18日
    5400
  • 加权融合c语言,加权框融合wbf

    C语言遇到了问题 输入字符的格式与要求不一致。在用%c格式输入字符时,空格字符和转义字符都作为有效字符输入。 对于直接关闭窗口的问题是因为程序运行完毕得出结果的时间很快,所以你看到运行窗口一闪就关了。 系统显示两个错误,其实都是指向max的申明问题的。如下:在main函数中使用了max,但是max没有事先申明。C语言规定用户自定义的变量和函数都需要事先申明。…

    2024年5月18日
    3400
  • c语言strok,C语言struct

    c语言:如何把字符串分解为一个个的字符? 字符数组存放的。你把一个一个数组元素取出来用,就是单个字符啊。 可以使用strtok函数把一个字符数组分解成多个字符数组。 按题意,字符串之间没有空格,那么用指针循环每次跳一个分组长度来取每个分组,同时判断是0开头还是1开头,决定数组正取还是反取。 字符串可以包含多个字符。所以 单个字符转为字符串,只需要定义一个字符…

    2024年5月18日
    2900
  • c语言中画圆的程序,c语言 画圆

    用C语言写出画一个圆形的代码 1、circle函数是TURBO C提供的图形接口,用来画圆。不属于标准库函数,不具备可移植性。 2、你的c 编译器需带 绘图函数库 才行。c++ API 程序 可以绘图。只要得到窗口句柄,就可在该窗画图。画直线,多边形,圆,椭圆,扇形 等 都是基本函数。 3、可以试试opencv,开源库,老版本(应该2以下)都是c代码,要绘图…

    2024年5月18日
    3900
  • c语言与cjava,C语言与或非逻辑符号

    c语言与Java哪一个比较好呀? 从学习难度来看,Java语言要比C语言简单一些。因为c语言属于底层开发语言,算法逻辑较为复杂,例如指针、内存分配、释放等概念都需要我们掌握。 从优势和就业来看,java目前好一点,java是面向对象的高级语言,所以应用软件主要使用它,相比较C擅长的底层开发,应用软件的市场更大一些,所以也更容易就业一些,但是如果C学的非常好的…

    2024年5月18日
    3800

发表回复

登录后才能评论



关注微信