分享

[原创]c++语言程序设计超级简单了解 邪恶八进制信息安全团队官方论坛 - 努力为信息安全撑起一片蓝天 - EvilOctal Security Team - E.S.T

 intruder 2006-01-02

c++语言程序设计超级简单了解

信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])
文章作者:金州

c++语言程序设计超级简单了解


千里之行,始于足下。

这是非常非常非常表面的介绍,是为一点都不知道的朋友写着玩的。也许你看过之后什么都没有
收获到,一直骂作者是个sb.那么我请您原谅耽误了您的时间,先表示抱歉了。呵呵

一。结构程序设计方法,要点。.三种基本控制结构。顺序,循环,选择
选择结构,两种。if switch
if形式1.if   2. if else 3. if else if else if
switch(多分支选择,金州注释)
switch
{case 常量表达式1 :语句1
case 常量表达式n :语句n
default:语句n+1
}
循环,while(没有什么解释的,先判断,后执行,金州注释)
例子,求1到100整数和
#include <iostream.h>   (套入函数,金州注释)
 void main()         (下面主体,金州注释)
 {                
  int i, sum = 0;     (定义i,赋予数值1,总和开始为0,金州注释)
  i = 1;
  while(i <= 100) (循环下面部分,当i<100,判断条件,金州注释)
  {
   sum += i;   (加,一直加,金州注释)
   i++;
  }         (循环结束,金州注释)
  cout<<"sum = "<<sum;   (搞出来结果,字符串sum=那个结果。金州注释)
 }
do-while 循环(先执行,后判断)
例子,还举上面那个,就是求1到100整数和
#include <iostream.h>
 void main()
 {
  int i, sum=0;     (定义赋值。金州注释)
  i = 1;
  do             (下面是循环,金州注释)
  {
   sum += i;
   i++;
  }while(i<=100);   (条件,如果条件满足就循环,金州注释)
  cout<<"sum = "<<i;
 }
for循环,
例子,还是上面那个,求1到100整数和
#include <iostream.h>
 void main()
 {
  for(sum = 0, i = 1; i <= 100; i++)sum += i;
  cout<<"sum = "<<sum;
 }
(就是1-2-3-2-3-2-3(1指的是表达式),如果2不满足,结束。金州注释)

二,语言基础:
看例子比较方便了解,
//simple.cpp是一个简单的C++程序 (标准注释方法,不执行,我没有用这种注释,金州注释)
#include <iostream.h> (一个文件头,金州注释)
void main(void)   (函数,金州注释)
{             (main函数体开始标记,金州注释)
int i;         (声明一个变量,金州注释)
cout<<"jinzhou sb!";       (输出,后面的东西,金州注释)
cout<<"请输入一个整数:\n"; (\n是换行的意思,<<输出符号,金州注释)
cin>>i;               (输入,后面的东西。金州注释)
cout<<"输入的整数是:";  
cout <<i;
cout <<‘\n‘;   (上三行简写:cout<<"您输入的整数是:" <<i <<‘\n‘;)
}           (主体结束,金州注释)
(Visual C++6编译连接运行后,就是屏幕上出现“jinzhou sb!请输入一个整数”
然后你随便输入一个,回车,得到“输入的整数是:”,就是你输入的那个,大
概明白是这么个格式就行了。注意一点的就是,函数定义返回类型为void,不用返回
,如果定义为int,则不同。如下。金州注释。)
int main()
{
 …
 return 0;
}
(还有就是c++区分大小写,一般命令小写多,常量大写多。变量混用多。金州注释)
数据类型略过。大多类似的。
变量使用举一个简单的例子。
#include <iostream.h>
int main (void)  
{
int workDays = 5;     (定义一个整型变量,初始化为5,金州注释)
float workHours, payRate, weeklyPay;   (实型变量三个,金州注释)
workHours = 7.5; payRate = 38.55;   (赋值,金州注释)
weeklyPay = workDays * workHours * payRate; (乘法运算,金州注释)
cout << "Weekly Pay = " << weeklyPay << ‘\n‘; (输出换行,金州注释)
}

就是计算工资呢。
例子,打印给定半径的圆的面积和周长(有常量定义的实例程序)
void main()
{
 const double PI = 3.1415926535898;   (定义圆周率常量PI,金州注释)
 double radius;   (定义圆半径变量,金州注释)
 double area;   (定义圆面积变量,金州注释)
 double circumference;   (定义圆周长变量,金州注释,)
 cout << "输入半径 : ";   (输出,屏幕显示,金州注释)
 cin >> radius;       (输入,金州注释)
 area = PI*radius*radius; (面积公式,金州注释)
 circumference = 2.0*PI*radius;   (周长共识,金州注释)
 cout << "面积 " << radius << " is "
 << area << " \n";
 cout << "周长是 " << circumference   (输出到屏幕,金州注释)
<< ";
}
(注意定义常量的形式为 const 类型 名字 = 值。)


三,运算符和表达式
要注意的是:
+ + 自加(前缀) ++valuel + 10 // 得出16,valuel变为6
+ + 自加(后缀) valuel++ + 10 // 得出15,valuel变为6
- - 自减(前缀) --valuel + 10 // 得出14,valuel变为4
- - 自减(后缀) valuel-- + 10 // 得出15,valuel变为4
(其实质就是用‘++‘代替了"+1"(后缀)和"1+"(前缀)、‘-‘代替了"-1"。金州注释)

!   逻辑非   !(5 = = 5) // 得出 0     (0是假,1是真,金州注释)
&&   逻辑与   5 < 6 && 6 < 6 // 得出 0
||   逻辑或   5 < 6 || 6 < 5 // 得出 1
~   取反 ~‘\011‘ // 得出 ‘\366‘
&   逐位与 ‘\011‘ & ‘\027‘ // 得出‘\001‘
|   逐位或 ‘\011‘ | ‘\027‘ // 得出‘\037‘
^   逐位异或 ‘\011‘ ^ ‘\027‘ // 得出‘\036‘
<< 逐位左移 ‘\011‘ << 2 // 得出‘\044‘
>> 逐位右移 ‘\011‘ >> 2 // 得出‘\002‘
实例 10进制值 二进制值
x   011     0 0 0 0 1 0 0 1
y   027     0 0 0 1 0 1 1 1
~x   366     1 1 1 1 0 1 1 0
x & y 001     0 0 0 0 0 0 0 1
x | y 037     0 0 0 1 1 1 1 1
x ^ y 036     0 0 0 1 1 1 1 0
x << 2 044   0 0 1 0 0 1 0 0
x >> 2 002   0 0 0 0 0 0 1 0
运算例子,
#include <iostream.h>
void main( )
{
 int a,b, m=3,n=4;
 a=7*2+-3%5-4/3;//-3%5=-3,4/3=1
 b=m++ - --n;
 cout<<a<<"\t"<<b<<"\t"<<m<<"\t"<<n<<endl;
}
结果10 0 4 3
例子
#include <iostream.h>
void main( )
{
 char x=‘m‘,y=‘n‘;
 int n;
 n=x<y;
 cout <<n<<endl;
 n=x==y-1;
 cout<<n<<endl;
 n=(‘y‘!=‘Y‘)+(5<3)+(y-x==1);
 cout <<n<<endl;
}
结果 1 1 2

四,流程控制语句。
if语句;if-else语句;switch语句;while语句;do-while语句;for语句;break语句;continue语句
(都是简单英语,没有什么解释的,哈哈,金州注释)
五,函数。
这个解释多多网上。
举例子;求长方形面积。
#include<iostream.h>   (C++库函数说明,金州注释)
int area(int length, int width);   ( area函数说明,定义长宽,金州注释)
void main()     (主函数,程序从该函数开始执行,金州注释)
{
 int this_length, this_width;   (定义长宽,金州注释)
 cout << "输入长度: "; (cout和cin,就是函数,输出后面字符串。金州注释)
 cin >> this_length;   (输入,金州注释)
 cout << "输入宽度: ";   (输出那句话到屏幕,金州注释)
 cin >> this_width;
 cout << "\n";         (回车,金州注释)
 cout << "面积 " << this_length << "x" << this_width;
 cout << " 长方形面积是 " << area(this_length, this_width); (调用area函数,金州注释)
}
int area(int length, int width) (area函数定义,金州注释)
{
 int number;
 number = length * width;
 return number;
}
例子,比较大小的。
#include <iostream.h>
int max(int a,int b) (调用这个函数,金州注释)
{
 if(a>b)return a; (如果则怎么怎么的,金州注释)
 else return b;
}           (以上是定义max函数的,金州注释)
void main()
{
 int max(int a,int b);
 int x,y,z;
 cout<<"输入两个数"<<endl; (屏幕显示,回车输入)
 cin>>x>>y;
 z=max(x,y);             (z为比较结果,金州注释)
 cout<<"最大的数="<<z;     (输出,金州注释)
}
例子

#include <iostream.h>
void Foo (int num)
{
 num = 0;
 cout << "num = " << num << ‘\n‘;
}
int main (void)
{
 int x = 10;
 Foo(x);
 cout << "x = " << x << ‘\n‘;
 return 0;
}
(这个更简单,不多说,主要是明白num是一个形参变量num,x是实参变量,实参调用时
送到形参,但是因为内存单元不同,即使num赋值0,并不影响x的值,道理大概理解了
就好,金州注释)
(不多解释了,相关详细内容,要找资料好好揣摩,这里只是简单说一下,金州注释)

六,数组与字符串。
#include <iostream.h>
void main(void)
{
 int marks[4] = {82,92,95,88}; (这个就是数组,就是这个格式,金州注释)
 cout<<"第二个元素是:"<<marks[1]<<endl; (四个数排序是0123,所以1是第二个元素,金州注释)
}
(这就是定义数组了,找第二个元素的。92。金州注释)
例子,求字符串的长度 (这个是字符串的,金州注释。)
#define MAXLEN 80
#include <stdio.h>
void main(void)
{
 char str[MAXLEN + 1];   (最长加1,因为是从0计算的,金州注释)
 int l;           (定义长度,这个符号可不是1啊,金州注释)
 printf("Input a string:"); (输出,告诉你开始输入,金州注释)
 scanf("%s",str);       (检查你输入的,如果空,金州注释)
 l = 0;             (长度0,金州注释)
 while(str[l] != ‘\0‘) (非空,金州注释)
 l ++;             (加加,数出来,金州注释)
 printf("The length of this string is %d\n",l); (输出结果回车,金州注释)
}

七,指针与引用
指针就是在内存中的地址,它可能是变量的地址,也可能是函数的入口地址。
引用为变量提供了一个别名,变量通过引用访问与通过变量名访问是完全等价的。
引用提供了与指针相同的能力,但比指针更为直观,更易于理解。
int d =1;
int* const p =&d
(有const表示不可修改,p是一个常量指针,它指向一个整型变量。就是d,p本
身不能修改,但它所指向的内容却可以修改:*p =2;这个不大好说,请查阅相
严谨详细资料。关金州注释。)
例如:
#include <iostream.h>
#define SIZE 10  
void main()
{
 int array[SIZE]; (声明整数数组,金州注释)
 int *p=array;     (定义一个整型指针p,给他数组首地址,金州注释)
 int i ;         (定义变量i,金州注释)
 for(i=0;i<SIZE;i++)   (赋值,运算,金州注释)
  array[i]=i;
 for(i=0;i<SIZE;i++)
  cout<<*p++<<endl;   (*p++就是访问下一个数组元素,金州注释)
 p=&array[8];     (给他array[8]的地址,金州注释)
 cout<<"array[8]="<<*p<<endl;     (输出*p,金州注释)
 cout<<"array[8]="<<array[8]<<endl; (输出array[8],金州注释)
}  
(两个值是一样的,因为从0开始,所以都是对数组第9个元素的访问。金州注释)
例子:折半查找函数
int BinSearch (char *item, char *table[],     (就是在table中查找是否含有item的元素)
int n, int (*Compare)(const char*, const char*))   Compare是一个比较函数指针,金州注释)
{
 int bot = 0;     (底部0,金州注释)
 int top = n - 1;   (顶部n-1,金州注释)
 int mid, cmp;   (定义比较变量,比较,金州注释)
while (bot <= top) (比较当然需要循环,循环条件,意思就是不空,金州注释)
 {           (以下循环内容)
mid = (bot + top) / 2;   (mid等于,全部除以2,就是一半,金州注释)
if ((cmp = Compare(item,table[mid])) == 0) (如果恰好相等,金州注释)
 return mid;   ( 就是它,金州注释)
 else if (cmp < 0) (不相等,金州注释)
    top = mid - 1; ( 查找数组的下半部,金州注释)
   else
    bot = mid + 1;   ( 查找数组的上半部,金州注释)
 }
return -1; (上面循环之后,返回-1,没有找到,因为n就是0了。金州注释)
}

例如。
char *cities[] = {"Beijing", "Shanghai", "Tianjin", "Zhongqing"};
cout << BinSearch("Tianjin ", cities, 4, strcmp) << ‘\n‘
输出结果2
(就是,给出一个数组,找找“Tianjin”在四个中的位置,2就是在第三个位置。)

八。结构 链表
结构(struct)数据类型,它能够识别一组相关的数据。
链表也是表示线性数据最有用的方法之一,用链表保存线性数据,可以克服数组的问题
举例
#include <iostream.h>
#include <string.h>
struct Person_Info {   (个人信息表,下面是相关内容。金州注释)
 char name[10];
 int age;
 long ssn;
};
void main (void)
{
 Person_Info* p1;     (给个指针,金州注释)
 p1 = new Person_Info;   (申请内存,金州注释)
 p1->age = 27; ( 给age成员赋值,金州注释)
 strcpy(p1->name,"jinzhou"); (给name成员赋值 ,金州注释)
 cout << "Name: " << p1->name << endl; ( 打印name成员,金州注释)
 cout << "Age: " << p1->age << endl; (打印age成员,金州注释)
 delete p1;                 (释放申请的内存,金州注释)
}
简单例子学生结构的实例
struct stu
  {
   int num;
   int score;
   stu *next;
  }
(明白这个意思就行了,金州注释)

九,编译预处理
C++提供的编译预处理功能主要有以下三种:(一) 宏定义(二) 文件包含(三) 条件编译
宏定义例子;
#include <iostream.h>, (一定要有,或者出错,金州注释)
#define CUBE_THREE 3*3* (用简单宏定义定义了一个符号常量"CUBE_THREE")
void main()
{
 int a;           (定义变量,金州注释)
 a=CUBE_THREE;     (赋予值,就是a=3*3*3,金州注释)
 cout<<"a is"<<a<<endl;   (输出,结果为27,金州注释)
}
(这个意思主要是说可以把常用的东西定义为宏。这个不带参数,带参数的略。金州注释)
文件包含类的略。
例子:条件编译命令的一个例子
#include <iostream.h>
#define TIME
void main()
{
 #ifdef TIME             (如果TIME被定义过,输出下面句话。金州注释)
  cout<<"Now begin to work"<<endl;
 #else               (如果没有定义,输出下面的,金州注释)
  cout<<"You can have a rest"<<endl;
 #endif
}
(所谓条件,就是有条件的,金州注释。就是要选择。哈哈)

十。类与对象
略过,请找寻相关详细资料阅读,不好意思。

十一,继承与多态。(略过)
十二,输入输出流。
抽象流基类
ios         流基类
输入流类
istream       普通输入流类和用于其它输入流的基类
ifstream      输入文件流类
istream_withassign 用于cin的输入流类
istrstream     输入串流类
输出流类
ostream      普通输出流类和用于其它输出流类的基类
ofstream      输出文件流类
ostream_withassign 用于cout、cerr和clog的流类
ostrstream.    输出串流类
输入输出流类
iostream      普通输入输出流类和用于其它输入输出流的基类
fstream      输入输出文件流类
strstream     输入输出串流类
stdiostream    用于标准输入输出文件的输入输出类
缓冲流类
streambuf     抽象缓冲流基类
filebuf      用于磁盘文件的缓冲流类
strstreambuf.   用于串的缓冲流类
stdiobuf      用于标准输入输出文件的缓冲流类
预定义流初始化类
iostream_init   预定义流初始化的类
其中,ios、istream、ostream和streambuf类构成了C++中iostream输入输出功能的基础
(略)

  如果你真的捏着鼻子再捏着鼻子读完的话,也许和我一样觉得算是了解了c++九牛一毛了,
其实后来才发现不过是才知道牛是有毛的而已。到现在我也没有抓住牛头,据说编程需要天才,
我没有哪个天分,哈哈,只是希望有朋友看到之后能够有一个很大概地了解。不好意思。不过大家可
以常常到邪恶八进制来看看,这里有很多这方面的超级高手,至少算是看看天才的样子,哈哈
祝福!
                              金州。邪恶八进制
                                  2005.12.17


 

 

定义常量也可以使用define、inline去实现

我建议大家用const和inline而不用#define

这个条款最好称为:“尽量用编译器而不用预处理”,因为#define经常被认为好象不是语言本身的一部分。这是问题之一。再看下面的语句:

#define ASPECT_RATIO 1.653

编译器会永远也看不到ASPECT_RATIO这个符号名,因为在源码进入编译器之前,它会被预处理程序去掉,于是ASPECT_RATIO不会加入到符号列表中。如果涉及到这个常量的代码在编译时报错,就会很令人费解,因为报错信息指的是1.653,而不是ASPECT_RATIO。如果ASPECT_RATIO不是在你自己写的头文件中定义的,你就会奇怪1.653是从哪里来的,甚至会花时间跟踪下去。这个问题也会出现在符号调试器中,因为同样地,你所写的符号名不会出现在符号列表中。
解决这个问题的方案很简单:不用预处理宏,定义一个常量:

const double ASPECT_RATIO = 1.653;

这种方法很有效。但有两个特殊情况要注意。
首先,定义指针常量时会有点不同。因为常量定义一般是放在头文件中(许多源文件会包含它),除了指针所指的类型要定义成const外,重要的是指针也经常要定义成const。例如,要在头文件中定义一个基于char*的字符串常量,你要写两次const:

const char * const authorName = "Scott Meyers";

关于const的含义和用法,特别是和指针相关联的问题,参见条款21。

另外,定义某个类(class)的常量一般也很方便,只有一点点不同。要把常量限制在类中,首先要使它成为类的成员;为了保证常量最多只有一份拷贝,还要把它定义为静态成员:
     

class GamePlayer {
private:
      static const int NUM_TURNS = 5; // constant eclaration  
      int scores[NUM_TURNS];                 // use of constant
      ...
};

还有一点,正如你看到的,上面的语句是NUM_TURNS的声明,而不是定义,所以你还必须在类的实现代码文件中定义类的静态成员:

const int GamePlayer::NUM_TURNS;         // mandatory definition;
              // goes in class impl.file

你不必过于担心这种小事。如果你忘了定义,链接器会提醒你。

旧一点的编译器会不接受这种语法,因为它认为类的静态成员在声明时定义初始值是非法的;而且,类内只允许初始化整数类型(如:int, bool, char 等),还只能是常量。
在上面的语法不能使用的情况下,可以在定义时赋初值:


class EngineeringConstants { // this goes in the class
private:                 // header file
      static const double FUDGE_FACTOR;
      ...
};
      // this goes in the class implementation file
      const double EngineeringConstants::FUDGE_FACTOR = 1.35;

大多数情况下你只要做这么多。唯一例外的是当你的类在编译时需要用到这个类的常量的情况,例如上面GamePlayer::scores数组的声明(编译过程中编译器一定要知道数组的大小)。所以,为了弥补那些(不正确地)禁止类内进行整型类常量初始化的编译器的不足,可以采用称之为“借用enum”的方法来解决。这种技术很好地利用了当需要int类型时可以使用枚举类型的原则,所以GamePlayer也可以象这样来定义:


class GamePlayer {
private:
      enum { NUM_TURNS = 5 }         // "the enum hack" — makes
      // NUM_TURNS a symbolic name  
      // for 5
      int scores[NUM_TURNS];// fine
};

除非你正在用老的编译器(即写于1995年之前),你不必借用enum。当然,知道有这种方法还是值得的,因为这种可以追溯到很久以前的时代的代码可是不常见的哟。

回到预处理的话题上来。另一个普遍的#define指令的用法是用它来实现那些看起来象函数而又不会导致函数调用的宏。典型的例子是计算两个对象的最大值:


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

这个语句有很多缺陷,光想想都让人头疼,甚至比在高峰时间到高速公路去开车还让人痛苦。
无论什么时候你写了象这样的宏,你必须记住在写宏体时对每个参数都要加上括号;否则,别人调用你的宏时如果用了表达式就会造成很大的麻烦。但是即使你象这样做了,还会有象下面这样奇怪的事发生:

int a = 5, b = 0;
max(++a, b);// a 的值增加了2次
max(++a, b+10); // a 的值只增加了1次

这种情况下,max内部发生些什么取决于它比较的是什么值!
幸运的是你不必再忍受这样愚笨的语句了。你可以用普通函数实现宏的效率,再加上可预计的行为和类型安全,这就是内联函数(见条款33):


inline int max(int a, int b) { return a > b ? a : b; }
不过这和上面的宏不大一样,因为这个版本的max只能处理int类型。但模板可以很轻巧地解决这个问题:


template<class T>
inline const T& max(const T& a, const T& b)
{ return a > b ? a : b; }

这个模板产生了一整套函数,每个函数拿两个可以转换成同种类型的对象进行比较然后返回较大的(常量)对象的引用。因为不知道T的类型,返回时传递引用可以提高效率(见条款22)。

顺便说一句,在你打算用模板写象max这样有用的通用函数时,先检查一下标准库(见条款49),看看他们是不是已经存在。比如说上面说的max,你会惊喜地发现你可以后人乘凉:max是C++标准库的一部分。
有了const和inline,你对预处理的需要减少了,但也不能完全没有它。抛弃#include的日子还很远,#ifdef/#ifndef在控制编译的过程中还扮演重要角色。预处理还不能退休,但你一定要计划给它经常放长假。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多