网站商品页面设计,软件开发公司排名,中企动力科技股份有限公司潍坊分公司,怎么做网站网站吗C中CONST的使用#xff1a; 虽然这听起来很简单#xff0c;但实际上#xff0c;const的使用也是c语言中一个比较微妙的地方#xff0c;微妙在何处呢#xff1f;请看下面几个问题。 问题#xff1a;const变量 常量 为什么下面的例子在使用一个const变量…C中CONST的使用 虽然这听起来很简单但实际上const的使用也是c语言中一个比较微妙的地方微妙在何处呢请看下面几个问题。 问题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 im hungry!; p[0] I; 答案与分析 上面的代码可能会造成内存的非法写操作。分析如下 im hungry实质上是字符串常量而常量往往被编译器放在只读的内存区不可写。p初始指向这个只读的内存区而p[0] I则企图去写这个地方编译器当然不会答应。 问题const变量 字符串常量2 请问char a[3] abc 合法吗使用它有什么隐患 答案与分析 在标准C中这是合法的但是它的生存环境非常狭小它定义一个大小为3的数组初始化为abc注意它没有通常的字符串终止符/0因此这个数组只是看起来像C语言中的字符串实质上却不是因此所有对字符串进行处理的函数比如strcpy、printf等都不能够被使用在这个假字符串上。 问题5const 指针 类型声明中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就是修饰指针本身即指针本身是常量。你可以根据这个规则来看上面声明的实际意义相信定会一目了然。 另外需要注意对于const (char *) ; 因为char *是一个整体相当于一个类型(如 char)因此这时限定指针是const。 编辑本段C中CONST 一简单介绍把握全局 const与define指针引用函数类成员 1.》》const与define。两者都可以用来定义常量但是const定义时定义了常量的类型所以更精确一些。#define只是简单的文本替换除了可以定义常量外还可以用来定义一些简单的函数有点类似内置函数。const和 define定义的常量可以放在头文件里面。小注可以多次声明但只能定义一次 2.》》const与指针和引用。 aconst与指针。 先来看看下面的几种定义 int me const int * p1me//p1可变*p1不可变但是不能用*p1来修改p1可以转向 int * const p2me//p2不可变*p2可变此时允许*p2来修改其值但是p2不能转向。 const int *const p3me//p3不可变*p3也不可变此时既不能用*p3来修改其值也不能转向 第一个const的意思是对p1来讲它指向的就是const常量虽然me不是但是对p1来说就是。 b指针和引用的的区别很简单就是引用更简洁更安全。因为引用声明是必须初始化。 引用更接近const指针一旦与某个变量关联就将一直效忠于他。 cconst指针可以接受const和非const地址但是非const指针只能接受非const地址。所以const指针的能力更强一些所以尽量多用const指针这是一种习惯。 3.》》aconst与函数。由于 c所以经常把函数的形参类型设为const而且多为const 引用。但是这里有一个限制不能把不是左值的地址传递给引用。左值包括变量数组元素结构成员引用被解除引用的指针等。 形参是const类型的说明该函数将不会修改其值该函数便为const函数。 bconst与类成员函数。先看看下面这段代码 const Stock land Stock(hyd); land.show(); land 是常量但是类成员函数show无法保证不修改land所以编译器将拒绝执行该段代码。除非你能保证show像const函数一样但这需要另外一种语法即 void show() const;(声明) void Stock::show() const{}(定义)。 二详细介绍注重细节 C中常用:“ #define 变量名 变量值”定义一个值替代,然而却有个致命缺点:缺乏类型检测机制,这样预处理在C中成为可能引发错误的隐患,于是引入const. const使用: 1. 用于指针的两种情况:const是一个左结合的类型修饰符. int const *A; //A可变,*A不可变 int *const A; //A不可变,*A可变 2.限定函数的传递值参数: void function(const int Var); //传递过来的参数在函数内不可以改变. 3.限定函数返回值型. const int function(); //此时const无意义 const myclassname function(); //函数返回自定义类型myclassname. 4限定函数类型. void function()const; //常成员函数, Const成员函数不能改变对象的成员函数。 例如 int Point::GetY() { return yVal; } 这个函数被调用时不改变Point对象而下面的函数改变Point对象 void Point:: SetPt (int x, int y) { xValx; yValy; } 为了使成员函数的意义更加清楚我们可在不改变对象的成员函数的函数原型中加上const说明 class Point { public: int GetX() const; int GetY() const; void SetPt (int, int); void OffsetPt (int, int); private: int xVal, yVal; }; const成员函数应该在函数原型说明和函数定义中都增加const限定 int Point::GetY() const { return yVal; } class Set { public: Set (void){ card 0; } bool Member(const int) const; void AddElem(const int); //... }; bool Set::Member (const int elem) const { //... } 非常量成员函数不能被常量成员对象调用因为它可能企图修改常量的数据成员 const Set s; s.AddElem(10); // 非法: AddElem不是常量成员函数 s.Member(10); // 正确 *******但构造函数和析构函数对这个规则例外它们从不定义为常量成员但可被常量对象调用被自动调用。它们也能给常量的数据成员赋值除非数据成员本身是常量。 为什么需要const成员函数 我们定义的类的成员函数中常常有一些成员函数不改变类的数据成员也就是说这些函数是只读函数而有一些函数要修改类数据成员的值。如果把不改变数据成员的函数都加上const关键字进行标识显然可提高程序的可读性。其实它还能提高程序的可靠性已定义成const的成员函数一旦企图修改数据成员的值则编译器按错误处理。 const成员函数和const对象 实际上const成员函数还有另外一项作用即常量对象相关。对于内置的数据类型我们可以定义它们的常量用户自定义的类也一样可以定义它们的常量对象。例如定义一个整型常量的方法为 const int i1 同样也可以定义常量对象假定有一个类classA定义该类的常量对象的方法为 const classA a(2) 这里a是类classA的一个const对象2传给它的构造函数参数。const对象的数据成员在对象寿命期内不能改变。但是如何保证该类的数据成员不被改变呢 为了确保const对象的数据成员不会被改变在C中const对象只能调用const成员函数。如果一个成员函数实际上没有对数据成员作任何形式的修改但是它没有被const关键字限定的也不能被常量对象调用。下面通过一个例子来说明这个问题 class C { int X; public: int GetX() { return X; } void SetX(int X) { this-X X; } }; void main() { const C constC; coutconstC.GetX(); } 如果我们编译上面的程序代码编译器会出现错误提示constC是个常量对象它只能调用const成员函数。虽然GetX( )函数实际上并没有改变数据成员X由于没有const关键字限定所以仍旧不能被constC对象调用。如果我们将上述代码中 int GetX() 改写成 int GetX()const 再重新编译就没有问题了。 const成员函数的使用 const成员函数表示该成员函数只能读类数据成员而不能修改类成员数据。定义const成员函数时把const关键字放在函数的参数表和函数体之间。有人可能会问为什么不将const放在函数声明前呢因为这样做意味着函数的返回值是常量意义完全不同。下面是定义const成员函数的一个实例 class X { int i; public: int f() const; }; 关键字const必须用同样的方式重复出现在函数实现里否则编译器会把它看成一个不同的函数 int X::f() const { return i; } 如果f( )试图用任何方式改变i或调用另一个非const成员函数编译器将给出错误信息。任何不修改成员数据的函数都应该声明为const函数这样有助于提高程序的可读性和可靠性。