您的位置:首页 > 编程语言 > C语言/C++

[2015.8.5]C++学习总结

2015-08-05 18:16 387 查看
【1】宏定义:(简单说句就是用其他的名字来代表一些可能会重复出现,或是繁琐的东西)
无参宏定义:
无参宏定义的一般形式为:#define 标识符 字符串
其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。
例如: #define M (a+b) 它的作用是指定标识符M来代替表达式(a+b)。在编写源程序时,所有的(a+b)都可由M代替,而对源程序作编译时,将先由预处理程序进行宏代换,即用(a+b)表达式去置换所有的宏名M,然后再进行编译。
程序1:

#include <iostream>
#define M (x+y)
using namespace std;
int main()
{
int x,y;
cin>>x>>y;
cout<<"x+y= "<<M<<endl;
return 0;

}

对于宏定义还要说明以下几点:
1.宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。
2.宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。
3.宏定义其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。  (有关#undef 请查阅其他资料)

有参宏定义:
c语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。
带参宏定义的一般形式为:  #define 宏名(形参表) 字符串
在字符串中含有各个形参。 带参宏调用的一般形式为:  宏名(形参表)
例如:

#defineM(y)((y)*(y)+3*(y))/*宏定义*/
k=M(5);/*宏调用*/
在宏调用时,用实参5去代替形参y,经预处理宏展开后的语句为:  k=5*5+3*5
程序2:
#include <iostream>
#define M(x,y) x+y
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
cout<<"x+y= "<<M(a,b)<<endl;
return 0;
}
上例程序的第一行进行带参宏定义,用宏名M表示条件表达式 x+y ,形参a,b均出现在条件表达式中。程序中 M(x,y)=M(a,b) 为宏调用,实参a,b,将代换形参x,y。

【2】初步了解断点调试:C/C++ code:
f9 —— 设置/取消断点
f10 —— 单步执行
f11 —— 比f10的步幅小
f10在函数的调用时,直接跳过,在f11下,会进入函数体! 
f5 —— 执行到下一个断点!

了解调试,首先要知道"断点"这个概念。断点就是程序运行中可能会中断的地方,方便开发者在程序运行的过程中查看

程序当前的运行状态,比如变量的值,函数的返回值等等。究竟怎么使用断点呢?
1.F9在当前光标所在的行下断点,如果当前行已经有断点,则取消断点。
F5调试状态运行程序,程序执行到有断点的地方会停下来。
F10单步执行程序。

CTRL+F10运行到光标所在行。

F11和F10的区别是,如果当前执行语句是函数调用,则会进入函数里面。

SHIFT+F11跳出当前所在函数。

特别说明:

a.有的地方不能下断点。比如空行,基本类型定义语句(不初始化),等等非执行语句。比如

int i; // 此行不能下断点

int j=0;// 这里可以下

CString str;// 这里可以下

intk = Max(i,j);// 这里可以下

b.不是所有断点都会(断)。比如下断点的语句在程序里面没有被执行。

c.此外,ALT+F9还可以下条件断点,不过这个不常用,有兴趣的可以自己研究
2.如何调试Release版的程序?

有些程序在debug下运行的很好,但在release下却总是失败,默认情况下release是不能调试的。 怎么解决呢?

其实"debug"和"release"都只是一个代号而已,各自对应一组不同的编译选项。

在release的默认设置下,ALT+F7 ,调出工程设置对话框,切换到link选项卡,勾选"Generate debug info",然后再切换

到C/C++选项卡,在"Optimizations"里面选"Disable(Debug)",在下面的"Debug info"里面选"Program Database for Edit

and Continue".然后点OK保存设置,重新编译程序,下断点即可。

3.上面两点已经能应付很多种情况了,但是有时候即使在debug下也不能下断点,我以前也曾经遇到过这种问题,一个

调了层的dll,就是不能下断点。其实还除了上面的方法,还有一种最底层的实现技术:使用汇编。

细心的人可能会发现,有时候在调试状态下当程序出现异常的时候,光标会指向汇编代码,而这个代码就是int 3,这其

实是一个中断。

在你的代码的任意地方加上

__asm

{

int 3

};

用debug编译,然后直接运行程序。当程序执行到上述代码的时候,就会出现一个框,告诉你说一大堆信息,说程序错
了,下面有"调试"、"终止"、"忽略",不用理,点调试就可以进入跟踪了。
(BUG与Debug的由来:为马克1号编制程序的是一位女数学家雷斯.霍波,有一天,她在调试程序时出现故障,拆开继电器后,发现有只飞蛾被夹扁在触点中间,从而“卡”住了机器的运行。于是,霍波诙谐的把程序故障统称为“臭虫(BUG)”,把排除程序故障叫DEBUG,而这奇怪的“称呼”,竟成为后来计算机领域的专业行话。)

【3】初步了解二分法查找:(具体感悟下次在发表)
算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。主要思想是:(设查找的数组区间为array[low, high])(1)确定该期间的中间位置K(2)将查找的值T与array[k]比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。区域确定如下:a.array[k]>T 由数组的有序性可知array[k,k+1,……,high]>T;故新的区间为array[low,……,K-1]b.array[k]<T
类似上面查找区间为array[k+1,……,high]。每一次查找与中间值比较,可以确定是否查找成功,不
be8d
成功当前查找区间缩小一半。递归找,即可,时间复杂度:O(log2n)。
c++代码:
#include<iostream>
#define N 10
using namespace std;
int main()
{
int a
,front,end,mid,x,i;
cout<<"请输入已排好序的a数组元素:"<<endl;
for(i=0;i<N;i++)
cin>>a[i];
cout<<"请输入待查找的数x:"<<endl;
cin>>x;
front=0;
end=N-1;
mid=(front+end)/2;
while(front<end&&a[mid]!=x)
{
if(a[mid]<x)front=mid+1;
if(a[mid]>x)end=mid-1;
mid=(front+end)/2;
}
if(a[mid]!=x)
printf("没找到!\n");
else
printf("找到了,在第%d项里",mid+1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: