啪啪拉拉噼里啪啦

初学者天堂资料汇集

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  16 随笔 :: 73 文章 :: 16 评论 :: 0 Trackbacks

程序基本原理
1.什么是计算机语言?
计算机程序设计语言是计算机可以识别的语言,用于描述解决问题的方法,供计算机阅读和执行。
2.什么是指令?
所谓指令,是计算机可以识别的命令。
3.什么是面向对象?
面向对象的编辑语言将客观事务看作具有属性和行为(或称为服务)的对象,通过抽象找出同一类的共同属性(静态特征)和行为(动态特征),形成类。对象也就是一组属性和一组行为的构成
4.是么是面向对象的方法?
首先将数据和对数据的操作方法放在一起,作为一个相互依存,不可分离的整体--对象。对同类型的对象抽象出其共性,形成类。类中大多数数据,智能用本类方法进行处理。类通过一个简单的外部接口与外界发生关系。对象与对象之间通过消息进行通讯。
5.什么是类》
 具有相同属性和服务一组对象的集合
6.面向对象的软件开发
面向对象的分析(OOA) 面向对象设计(OOD) 面向对象编程(OOP) 面向对象测试(OOT) 面向对象的软件维护(OOSM)
7.程序类型
 翻译程序有三种不同的类型
汇编程序  编译程序 解释程序

二:C/C++基础
2.1一个简单的C/C++程序:
#include<iostream.h>
void main()
{ cout<<"hello world!"<<endl;
  cout<<"welcome to our c++ \n";
}
2.2字符集


字符集是构成C++的基本元素。
英文字母A-Z,a-z;
数字字符0-9;
特殊字符
空格 !  #  % ^&*()+=-<>/\" 等
标识符
以大写字母和小写字母以及下划线开始
可以有大写字母小写字母以及数字组成
大写字母和小写字母代表不同标识符
不能是C++关键字
2.3 C++的注释
/*                 */ 段落间的注释
// 一行一行的注释

常量:整型常量 (十进制 八进制 十六进制)
 十进制 【0-9】
八进制 【0/0--9  】
十六进制 【0x/0-9】

实型常量  一般形式  12.5 -12.5
                  指数形式 0.34E+2  -34.53e-4   实型常量 默认为double  如果后缀为F 则是float
字符常量
'A','a','d','?','$'  \nnn  八进制形式                                 '\X61'='a' 十六进制 \xnnn
字符串常量
"this is a string"

布尔常量
只有两个 false(假)   true(真)

变量 变量在使用之前一定要声明。
数据类型 变量名1,变量名2,变量名3,…………变量名N;
例如
int a,b;
folat v,r h;
在声明一个变量时也可以给它赋初值 : int a=3;
double f=4.55;
char c='3';
int a(4);

变量存储了行, 变量除具有数据类型外,还具有存储类型。
auto: 采用堆栈方式分配内存空间,属于暂时性存储。其存储空间可被若干变量多次覆盖
register:存放在通用寄存器内
extern: 在所有函数和程序段都可以引用
static: 在内存中以固定地址存放,整个程序运行期均有用

符号常量
符号常量在使用前一定要声明
const  类型说明符  常量名=常量值;
数据类型说明符 const 常量名 =常量值;

const  float pi=3.1415926;
符号常量在声明时一定要赋初值,否则时错误的
以下声明就是错误的
const float pi;
pi=3.1415926; // 这是错误的。

计算
C=i++; 现把i值赋给C
B=++i; 现使i +1 之后赋值给B

a+=3  等价 a=a+3
a+=a-=a*a 等价于  a=a+(a=a-(a*a))

逗号表达式
int a;
a=3*5,a*4  //最终结果是60;

条件运算符
表达式1?表达式2:表达式3
cout<<(score>=60?"pass":"fail");

sizeof(类型名)
或者sizeof(表达式)
计算某种类型的对象在内存所占的字节数


数据的输入和输出

C++中,将数据从一个对象到令一个对象的流动抽象为"流"

C++ I/O 流类库  iomanip.h
dec  数值数据采用十进制
Hex  数值采用16进制
Oct  数值采用8进制
Ws   取空白符
endl 换行符,刷新流
ENDS 插入空白符
setprecision(INT) 设置浮点数的小数位数
setw(int) 设置域宽


算法基本结构

顺序  选择 循环

1.用IF语句实现选择结构
if(表达式) 语句1
else 语句2

例如
if(x>y) cout<<x;
else
cout<<y;


if(表达式)  语句  例如  if(x>y) cout<<x;

判断一个年份是否为闰年
分析:
闰年年份被4整除不能被100整除,或者能被400整除。因此

isleapyear((year%4= =0&& year%100 !=0)||(year%400==0) );

if(isleapyear)
{cout<<"this year is leapyear"<<year;}
else
{cout<<"this year is not leapyear"<<year;}

多重选择结构
if(表达式1)
  if(表达式2)  语句1
esle 语句2
else
   if(表达式3)语句3
else
   语句4



例如

cin>>x>>y;
if(x!=y)
  if(x>y)
   cout<<x;
else cout<<y;
else
 cout<<"x=y"<<endl;


if   else  if 语句

if(表达式) 语句1
else if (2)   语句2
esle if(3) 语句3
esle   语句N;


switch 语句
switch( 表达式)
{ case  常量表达式1:语句1
        break;

  case  常量表达式n:  语句N
      break;
default:语句N+1
    break;

}

例如:

#include<iostream.h>
void main()
{ int day;
  cout<<"Please input day"<<endl;
  cin>>day;
  switch(day)
{  case 0: cout<<"sunday"<<end;
                break;
    case 1:  cout<<"monday"<<endl;
               break;
    case 6:  cout<<"saturday"<<endl;
                break;
default: cout<<"the error day!";
           break;

}

}


循环结构

while(i<10)
{ sum+=i[
  i++
}

do
{ sum=sum+i;
  i++;
} while(i<=10);

输入一个整数,将各位数字翻转后输出。。。

#include<iostram.h>
void main()
{ int n; right_digit;
   cout<<"enter the number";
  cin>>n;
 do
{  right_digit=n%10;
   cout<<right_digit;
  n=n/10;

} while(n!=0);
cout<<endl;
}

for yu语句
1..for(i=1;i<10;i++) sum=sum+i;
2..i=1;
    for(;i<10;i++) sum=sum+i;
3..for(i=0,j=0;i<=j;i++,j--) k=i+j;
4..for(i=0;i<10;)sum=sum+i;i++;
用FOR可以解决所有循环问题


求出一个数的所有因子
#include<iostream.h>
void main()
{ int n,k;
  for(k=1;k<=n;k++)
{  if(n%k==0)
   cout<<k<<"";
 cout<<endl;
}
}

自定义类型

typedef

typedef  int  natural;
natural t1,t2;

定义natural可以为整型变量

枚举类型  enum
enum  枚举类型名 {变量值列表}
enum weekday{sun,mon,tue,wed, thu,sat};
对枚举类型按照常量处理,但不能赋初值
枚举类型具有默认值 依次分别为0,1,2,3,4,…………等
也可在声明时另行指定枚举元素的值 如
enum weekday{sun=7,mon=1,………………};
整数值不能直接赋予枚举类型。若需将整数值赋给枚举变量,应进行强制类型转换
枚举可进行关系运算

例如
#include<iostream.h>
enum game_result(win lose tie cancel);
int main()
{ game_result result;
  emum game_result omit=cancel;
  int count;
 for(count=win;count<=cancel;count++)
 { result=(game_result)count;
  if(result=omit)
{cout<<"the game is cancelled";}
else
{ cout<<"the game was played";
 if(result=win)
  cout<<"and won";
if (result=lose)
cout<<"and lost"

}
}
return 0;
}


五个颜色不同的彩球,每次取三个,三个颜色均不相同。问有多少种取法。
5×4×3=60

enmu color {red,yellow,blue,white,black}
int i,j,k;
int n=0;
for(i=red;i<=black;i++)
  for(j=red;j<=black;j++)
    if(i!=j)
    { for(k=red;k<=black;k++)
         if((k!=i)&&(k!=j))
            { n=n+1 }
               cout<<n;
             
             for(loop=1;loop<=3;loop++)
                   { switch(loop)
                         {  case 1:pr1=(enum color)i;break;
                             case 2:pr1=(enum color)j;break;
                             case 3:pr1=(enum color)k;break;
                         default:break; }
                      switch(pr1)
                            {  case red: cout<<"red"; break;
                                case blue :^………………
                            ……………………
                              default:break;}
                           
          }}
              cout<<n;                     }

结构体变量
struct  student
{ int num;
   char name[20];
   char sex;
}
student  student1;
studen1.name="zhang san"

 

联合体
有时需要几个不同类型的变量共用一组内存单元,这时可以声明一个联合体类型

 union uarea
{ char c_data;
  long  i_data; }
联合体可以不声明名称,称之为无名联合体

posted on 2005-04-01 05:34 噼里啪啦的世界 阅读(784) 评论(5)  编辑  收藏

评论

# re: 我的java学习笔记(第一章 回顾C/C++ 基本概念) 2005-04-01 06:45 噼里啪啦的世界
问题:const变量 & 常量

  为什么我象下面的例子一样用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢?

  const int n = 5;

  int a[n];

  答案与分析:

  1)、这个问题讨论的是“常量”与“只读变量”的区别。常量肯定是只读的,例如5, “abc”,等,肯定是只读的,因为程序中根本没有地方存放它的值,当然也就不能够去修改它。而“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量n被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时维度必须是“常量”,“只读变量”也是不可以的。

  2)、注意:在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const int n,n只是一个变量(常量 != 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的),实际上,根据编译过程及内存分配来看,这种用法本来就应该是合理的,只是ANSI C对数组的规定限制了它。

  3)、那么,在ANSI C 语言中用什么来定义常量呢?答案是enum类型和#define宏,这两个都可以用来定义常量。

  问题:const变量 & const 限定的内容

  下面的代码编译器会报一个错误,请问,哪一个语句是错误的呢?

  typedef char * pStr;

  char string[4] = "abc";

  const char *p1 = string;

  const pStr p2 = string;

  p1++;

  p2++;

  答案与分析:

  问题出在p2++上。

  1)、const使用的基本形式: const char m;

  限定m不可变。

  2)、替换1式中的m, const char *pm;

  限定*pm不可变,当然pm是可变的,因此问题中p1++是对的。

  3)、替换1式char, const newType m;

  限定m不可变,问题中的charptr就是一种新类型,因此问题中p2不可变,p2++是错误的。

  问题:const变量 & 字符串常量

  请问下面的代码有什么问题?

  char *p = "i'm hungry!";

  p[0]= 'I';

  答案与分析:

  上面的代码可能会造成内存的非法写操作。分析如下, “i'm hungry”实质上是字符串常量,而常量往往被编译器放在只读的内存区,不可写。p初始指向这个只读的内存区,而p[0] = 'I'则企图去写这个地方,编译器当然不会答应。

  问题:const变量 & 字符串常量2

  请问char a[3] = "abc" 合法吗?使用它有什么隐患?

  答案与分析:

  在标准C中这是合法的,但是它的生存环境非常狭小;它定义一个大小为3的数组,初始化为“abc”,,注意,它没有通常的字符串终止符'\0',因此这个数组只是看起来像C语言中的字符串,实质上却不是,因此所有对字符串进行处理的函数,比如strcpy、printf等,都不能够被使用在这个假字符串上。

  问题:const & 指针

  类型声明中const用来修饰一个常量,有如下两种写法,那么,请问,下面分别用const限定不可变的内容是什么?

  1)、const在前面

  const int nValue; //nValue是const

  const char *pContent; //*pContent是const, pContent可变

  const (char *) pContent;//pContent是const,*pContent可变

  char* const pContent; //pContent是const,*pContent可变

  const char* const pContent; //pContent和*pContent都是const

  2)、const在后面,与上面的声明对等

  int const nValue; // nValue是const

  char const * pContent;// *pContent是const, pContent可变

  (char *) const pContent;//pContent是const,*pContent可变

  char* const pContent;// pContent是const,*pContent可变

  char const* const pContent;// pContent和*pContent都是const

  答案与分析:

  const和指针一起使用是C语言中一个很常见的困惑之处,在实际开发中,特别是在看别人代码的时候,常常会因为这样而不好判断作者的意图,下面讲一下我的判断原则:

  沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。

  另外,需要注意:对于const (char *) ; 因为char *是一个整体,相当于一个类型(如 char),因此,这是限定指针是const。

  回复  更多评论
  

# re: 我的java学习笔记(第一章 回顾C/C++ 基本概念) 2005-04-01 06:49 噼里啪啦的世界
一、typedef的用法

____在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:

typedef int INT;
typedef int ARRAY[10];
typedef (int*) pINT;

____typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。

二、#define的用法

____#define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:

#define INT int
#define TRUE 1
#define Add(a,b) ((a)+(b));
#define Loop_10 for (int i=0; i<10; i++)

____在Scott Meyer的Effective C++一书的条款1中有关于#define语句弊端的分析,以及好的替代方法,大家可参看。

三、typedef与#define的区别

____从以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量,到了C++,const、enum、inline的出现使它也渐渐成为了起别名的工具。有时很容易搞不清楚与typedef两者到底该用哪个好,如#define INT int这样的语句,用typedef一样可以完成,用哪个好呢?我主张用typedef,因为在早期的许多C编译器中这条语句是非法的,只是现今的编译器又做了扩充。为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。

____宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点代码的第三行:

typedef (int*) pINT;
以及下面这行:
#define pINT2 int*

____效果相同?实则不同!实践中见差别:pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。

____注意:两者还有一个行尾;号的区别哦!
  回复  更多评论
  

# re: 我的java学习笔记(第一章 回顾C/C++ 基本概念) 2005-04-01 06:50 噼里啪啦的世界

常量
常量是一种标识符,它的值在运行期间恒定不变。C语言用 #define来定义常量(称为宏常量)。C++ 语言除了 #define外还可以用const来定义常量(称为const常量)。
为什么需要常量
如果不使用常量,直接在程序中填写数字或字符串,将会有什么麻烦?
(1) 程序的可读性(可理解性)变差。程序员自己会忘记那些数字或字符串是什么意思,用户则更加不知它们从何处来、表示什么。
(2) 在程序的很多地方输入同样的数字或字符串,难保不发生书写错误。
(3) 如果要修改数字或字符串,则会在很多地方改动,既麻烦又容易出错。

【规则5-1-1】 尽量使用含义直观的常量来表示那些将在程序中多次出现的数字或字符串。
例如:
#define MAX 100 /* C语言的宏常量 */
const int MAX = 100; // C++ 语言的const常量
const float PI = 3.14159; // C++ 语言的const常量
const 与 #define的比较
C++ 语言可以用const来定义常量,也可以用 #define来定义常量。但是前者比后者有更多的优点:
(1) const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。
(2) 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

【规则5-2-1】在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。



  回复  更多评论
  

# re: 我的java学习笔记(第一章 回顾C/C++ 基本概念) 2005-04-01 06:52 噼里啪啦的世界
常量定义规则
【规则5-3-1】需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义文件的头部。为便于管理,可以把不同模块的常量集中存放在一个公共的头文件中。
【规则5-3-2】如果某一常量与其它常量密切相关,应在定义中包含这种关系,而不应给出一些孤立的值。
例如:
const float RADIUS = 100;
const float DIAMETER = RADIUS * 2;
类中的常量
有时我们希望某些常量只在类中有效。由于#define定义的宏常量是全局的,不能达到目的,于是想当然地觉得应该用const修饰数据成员来实现。const数据成员的确是存在的,但其含义却不是我们所期望的。const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。
不能在类声明中初始化const数据成员。以下用法是错误的,因为类的对象未被创建时,编译器不知道SIZE的值是什么。
class A
{…
const int SIZE = 100; // 错误,企图在类声明中初始化const数据成员
int array[SIZE]; // 错误,未知的SIZE
};

const数据成员的初始化只能在类构造函数的初始化表中进行,例如
class A
{…
A(int size); // 构造函数
const int SIZE ;
};
A::A(int size) : SIZE(size) // 构造函数的初始化表
{

}
A a(100); // 对象 a 的SIZE值为100
A b(200); // 对象 b 的SIZE值为200

怎样才能建立在整个类中都恒定的常量呢?别指望const数据成员了,应该用类中的枚举常量来实现。例如
class A
{…
enum { SIZE1 = 100, SIZE2 = 200}; // 枚举常量
int array1[SIZE1];
int array2[SIZE2];
};
枚举常量不会占用对象的存储空间,它们在编译时被全部求值。枚举常量的缺点是:它的隐含数据类型是整数,其最大值有限,且不能表示浮点数(如PI=3.14159)。

  回复  更多评论
  

# re: 我的java学习笔记(第一章 回顾C/C++ 基本概念) 2005-04-01 06:53 噼里啪啦的世界
const主要是为了程序的健壮型,减少程序出错.
最基本的用法:
const int a=100; b的内容不变,b只能是100也就是声明一个int类型的常量(#define b =100)
int const b=100; //和上面作用一样

const指针和引用一般用在函数的参数中
int* m = &a; //出错,常量只能用常指针
int c= 1;const int*pc = &c;//常指针可指向常量

const int* pa = &a; //指针指向的内容为常量(就是b的值不变)
int const *a = &b; //指针指向的内容为常量(就是b的值不变)*p=3//error
int* const a = &b; //指针为常量,不能更改指针了如 a++但可以改值*p=3;

从这可以看出const放在*左侧修饰的是指针的内容,const放在*右侧修饰的是指针
本身.

const引用的用法和指针一样
int const & a=b; 和指针一样
const int& a=b; 和指针一样
但没有 int& const a=b 的用法因为引用不能做移位运算,但只是出个warning

const int* const a = &b; //综合应用,一般用来传递多维的数组
类如:char* init[] = {"Paris","in the","Spring"};
void fun(const int* const a){}
fun(init)//保护参数不被修改

int A(int)const; //是常函数,只能用在类中,调用它的对象不能改改变成员值
const int A(); //返回的是常量,所以必须这么调用 cosnt int a=A();
int A(const int); //参数不能改值,可用在任意函数
int A(const int*);
....
int height() const;//常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height());

const int* pHeap = new int;
delete pHeap;
p = NULL;//出错
我的解决办法是强制类型转换
const int* pHeap = new int(1);
delete (int*)pHeap;
pHeap = NULL;

一、const 和引用联合使用的时候要注意

const int a = 1;
const int& ref1 = a;
const int& ref2 = 1;

ref1 和 ref2 都是正确的,但是他们引用的内容和一般的引用不同
对 const int& ref1 = a; 而言,其实这个 ref1 已经和 a 没有任何关系了
ref1 实际上是对一个临时量的引用。同理 const int& ref2 = 1; 也是对
一个临时量做的引用。当引用临时量是 C++ 的隐式类型转换可以起作用。
临时量的生存期和引用量的生存期相同。

二、强传const对象可能导致无定义行为

对于优化做的比较好的编译器,代码 const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数 1

const int i = 1;

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;

所以,对 const 对象做 const_cast 可能导致无定义行为
目前我就遇到这些问题,那位还有补充的吗





能不能把自己的经验也谈谈。大家交流交流
这个就是我在调错时发现的
int height() const;//常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height());





Thinking again in C++(一)常量性原理 cphj(原作)
有些地方很受启发


1.不能将const修饰的任何对象、引用和指针作为赋值表达式的左值。
const int cx=100;
const int & rcx=cx;
const int * pcx=&cx;
cx=200; //error
rcx=200; //error
*pcx=200; //error

2.const类型的对象不能直接被non-const类型的别名所引用。
(1)不能将const类型的对象传递给non-const类型的引用。
const int cx=100;
int & rx=cx; //error
(2)不能将const类型的实参传递给形参为non-const类型引用的函数。
void f(int a)
{
}
void g(int & ra)
{
}
const int cx=100;
f(cx); //ok
g(cx); //error
(3)不能将const类型的对象作为non-const类型引用的函数返回值。
int & f(const int & rca)
{
return rca; //error
}
int x=100;
f(x);

3.可以使用const类型别名引用non-const对象。此时通过const引用不能修改对象,但对象可以通过non-const引用被修改。
int x=100;
int & rx=x;
const int & rcx=x; //ok
x=200;
rx=200;
rcx=200; //error

4.指针的属性有两个:指针的类型和指针本身的常量性。其中,指向const对象与指向non-const对象,是不同的指针类型。
int x=100;
const int * pcx=&x; //[1]
int * px=&x; //[2]
int y=100;
int * const cpy=&y; //[3]
int * py=&y; //[4]
[1][2]两个指针的类型不同;[3][4]两个指针的常量性不同。
对象与指向对象的指针的规则类似于对象与引用。即,const类型的对象不能直接被non-const类型的指针所指示(同2);可以使用const类型的指针指向non-const对象(同3)。

5.可以将相同类型(包括常量性)的const指针值赋给non-const指针。
int x=100;
int * px;
const int * pcx=&x;
px=pcx; //error
int * const cpx=&x;
px=cpx; //ok

6.若函数的返回值为内建类型或是指针,则该返回值自动成为const性质。但自定义类型则为non-const性质。
int f() //相当于返回const int
{
return 100;
}
int * g(int & ra) //相当于返回int * const
{
return &ra;
}
class CTest
{
int n;
public:
CTest(int n){this->n=n;}
};
CTest h() //返回的就是CTest
{
return CTest(200);
}

f()=200; //error

int x=100;
int y=200;
int * px=&x;
g(y)=px; //error
*g(y)=x; //ok,从这点可以看出g()返回的不是const int *

CTest t(100);
h()=t; //ok,但却是完全错误的、危险的做法
//所以h()的正确写法是返回const CTest





const int b=100; b的内容不变,b只能是100
int const b=100; b必须为int型,不能为其他类型?
这2句话的意思应该是一样的吧 , THINKING IN C++是这样说的





const int a=100; a的内容不变,a只能是100(同样不能类型转换)。
int const b=100; b必须为int型,不能为其他类型?(同样在使用中不能修改)。
所以a和b是一样的,称为整型常数,在使用中不能被修改,当然都不能转为其他类型了。
#include <iostream>

using namespace std;

int main()
{
  const int a = 100;
  int const b = 100;

  a = 100; //这四条语句编译时都会出现“Cannot modify a const object
b = 100; //in function main()”的错误提示,也就是说,任何企图修改   a = 100.0; //a和b(其实是一样的)的行为都会出现“灾难”,在语法上讲就  b = 100.0; //是a和b都不能出现在赋值语句的左边!

  cout<<'\n'<<a<<'\n'<<b<<endl;

  return 0;
}





常函数的调用是这样的:常量对象只能调用常成员函数,非常量对象即可以调常成员函数,也可以调一般成员函数,但当某个函数有const和非const两个版本时,const对象调const版本,非const对象调非const版本
例:
class A
{
public:
int & GetData(){return data;}
const int & GetData()const {return data;}
private:
int data;
}
A a;
a.GetData();//调用int & GetData(){return data;}
//但如果没有这个函数,也可以调用const int & GetData()const
const A const_a;
const_a.GetData();//调用const int & GetData()const {return data;}
常函数只能调常函数,也是由于这个原因





算你狠!加两点

一、const 和引用联合使用的时候要注意

const int a = 1;
const int& ref1 = a;
const int& ref2 = 1;

ref1 和 ref2 都是正确的,但是他们引用的内容和一般的引用不同
对 const int& ref1 = a; 而言,其实这个 ref1 已经和 a 没有任何关系了
ref1 实际上是对一个临时量的引用。同理 const int& ref2 = 1; 也是对
一个临时量做的引用。当引用临时量是 C++ 的隐式类型转换可以起作用。
临时量的生存期和引用量的生存期相同。

二、强传const对象可能导致无定义行为

对于优化做的比较好的编译器,代码 const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数 1

const int i = 1;

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;

所以,对 const 对象做 const_cast 可能导致无定义行为





#include <iostream.h>
void fun(char b){cout <<"void"<<endl;}
int fun(int const b){cout <<"int"<<endl;}
int main()
{
fun(1.0);//详细看看重载函数吧
fun(4); //想一想调用哪一个

return 0;
}
我试了一下,会出错? vc说:'fun':ambiguous call to overloaded function





补充的好啊,这个一般不会注意的
const int i = 1;
*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;
这个可真有意思,调试时两个都是2,可编译就是2,1了
const的永远都是const,这样能更改就不错了,不然就自相矛盾了
奇怪的是 pi 和 &i地址一样啊,就像楼上说的这是编译时的优化
处理
const int i = 1;
int* pi=const_cast<int*>(&i);
*pi=2;
cout << *pi << endl;
cout << i << endl;





那个主要是隐式转换
你可依次把两个函数注掉看看调用
#include <iostream.h>
//void fun(char b){cout <<"void"<<endl;}
void fun(int b){cout <<"int"<<endl;}
int main()
{
fun('a');
fun(4);
return 0;
}


  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: