搜档网
当前位置:搜档网 › C语言中const的用法

C语言中const的用法

C语言中const的用法
C语言中const的用法

C语言中const的用法

基本解释

const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解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 = "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等,都不能够被使用在这个假字符串上。

问题5: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就是修饰指针本身,即指针本身是常量。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。

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

另=======

const用于函数时出现三个位置:

例如:

const returnVal function (const list_array)const;

第一个const意思是:返回值是常量

第二个const意思是:函数过程中不能修改list_array的值

第三个const意思是:函数过程不能隐式的修改function参数的值

===

zzhttps://www.sodocs.net/doc/e818019559.html,/blog/tb.b?diaryID=3217823

const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目。

Bjarne在他的The C++ Programming Language里面给出过一个助记的方法:把一个声明从右向左读。

char * const cp; ( * 读成pointer to ) :cp is a const pointer to char

const char * p; :p is a pointer to const char;

char const * p;

同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。

另:下面定义的一个指向字符串的常量指针:

char * const prt1 = stringprt1;

其中,ptr1是一个常量指针。因此,下面赋值是非法的。ptr1 = stringprt2;

而下面的赋值是合法的:*ptr1 = "m";

因为指针ptr1所指向的变量是可以更新的,不可更新的是常量指针ptr1所指的方向(别的字符串)。

下面定义了一个指向字符串常量的指针:

const * ptr2 = stringprt1;

其中,ptr2是一个指向字符串常量的指针。ptr2所指向的字符串不能更新的,而ptr2是可以更新的。因此,

*ptr2 = "x"; 是非法的,而:ptr2 = stringptr2; 是合法的。

所以,在使用const修饰指针时,应该注意const的位置。定义一个指向字符串的指针常量和定义一个指向字符串常量的指针时,const修饰符的位置不同,前者const放在*和指针名之间,后者const放在类型说明符前。

const int* a = &b 和const* int a = &b的区别收藏 如果const关键字不涉及到指针,我们很好理解,下面是涉及到指针的情况: int b = 500; const int* a = &b; [1] int const *a = &b; [2] int* const a = &b; [3] const int* const a = &b; [4] 如果你能区分出上述四种情况,那么,恭喜你,你已经迈出了可喜的一步。不知道,也没关系,我们可以参考《Effective c++》Item21上的做法,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。因此,[1]和[2]的情况相同,都是指针所指向的内容为常量(const放在变量声明符的位置无关),这种情况下不允许对内容进行更改操作,如不能*a = 3 ;[3]为指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如a++是错误的;[4]为指针本身和指向的内容均为常量。另外const 的一些强大的功能在于它在函数声明中的应用。在一个函数声明中,const 可以修饰函数的返回值,或某个参数;对于成员函数,还可以修饰是整个函数。有如下几种情况,以下会逐渐的说明用法: A& operator=(const A& a); void fun0(const A* a ); void fun1( ) const; // fun1( ) 为类成员函数 const A fun2( ); --------------------------------------------------------------------------------------------------------------------------------------------- const int * pi 、int const * pi与int * const pi及其操作 (本贴已经做了重大修改) 1 从const int i 说起

本文档含有三部分 第一部分 const的用法,特别是用在函数后面(第1-4页) 第二部分 C++的那点事,const,指针和引用的混合使用(第5-9页) 第三部分 const 总结(第10-13页) const的用法,特别是用在函数后面 在普通的非const成员函数中,this的类型是一个指向类类型的const指针(第 4.2.5 节)。可以改变this所指向的值,但不能改变this所保存的地址。在const成员函数中,this的类型是一个指向const类类型对象的const指针。既不能改变this所指向的对象,也不能改变this所保存的地址。 关键字:Const,Const函数,Const变量,函数后面的Const 看到const 关键字,C++程序员首先想到的可能是const 常量。这可不是良好的条件反射。如果只知道用const 定义常量,那么相当于把火药仅用于制作鞭炮。const 更大的魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。 const 是constant 的缩写,“恒定不变”的意思。被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多C++程序设计书籍建议:“Use const whenever you need”。 1.用const 修饰函数的参数 如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。const 只能修饰输入参数: 如果输入参数采用“指针传递”,那么加const 修饰可以防止意外地改动该指针,起到保护作用。 例如StringCopy 函数: void StringCopy(char *strDestination, const char *strSource); 其中strSource 是输入参数,strDestination 是输出参数。给strSource 加上const修饰后,如果函数体内的语句试图改动strSource 的内容,编译器将指出错误。 如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。 例如不要将函数void Func1(int x) 写成void Func1(const int x)。同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A 为用户自定义的数据类型。 对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。 为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void Func(A &a) 存在一个缺点: “引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)。

c语言if语句练习题 1、输入一个学生成绩,判断并输出该学生是否及格。 #include main { int a; printf ; scanf ; if printf ; else switch { case 0: case 1: case: case: case: case: printf ; break; 为B\n”); } }

2、输入三角形的三条边长,求三角形的周长和面积,若不能构成三角形,输出提示。拓展练习:根据用户输入的三角形的三条边长判定是何种三角形。 提示:正三角形——三边相等; 等腰三角形——三边中有两边相等; 直角三角形——两边的平房和等于第三边平方。 case: printf; break; case: printf; break; case: printf; #include #include main { float a,b,c,d; \n”); printf ; d=/2; if { if {printf ; printf ; } else { if { printf ; printf **),a+b+c); } else { if

{ printf ; printf **),a+b+c); } else { printf ; printf **),a+b+c); } } } } else printf ; } 3、输入3个分别表示箱子长、宽、高的整数值,判断并输出该箱子是正方体还是长方体。 ? 马克思手稿中有一道趣味数学题:有30个人,其中有男人、女人和小孩,在一家饭馆里吃饭 共花了50先令,每个男人各花3先令,每个女人各花2先令,每个小孩各花1先令,问男人、女人和小孩各有几人?

--------------------------CONST--------------------------------------- const应用: 一、对于基本声明 const int r=100;//标准const变量声明加初始化,编译器经过类型检查后直接用100在编译时替换。 二、对于指针 1. int x=10; const int *r=&x; //指针指向的内容是常量,r指向的内容不能够通过r改变,但如果是非const,内容可以通过自己改变,而且r指针可以改变,可以指向其它的整形. //*r=*r+1;NO //x++;YES //r=&y;YES 2. int const *r=&x; 与1完全相同 3. int * const r=&x; //指针指向是常量,不能修改去指向其它内容,但指向的内容可以修改 //r=&y;NO //*r=*r+1;YES //x++;YES 4.const int * const r=&x; //综合1、3用法,r是一个指向常量的常量型指针,指针指向不能改变,指针内容不能改变,内容可以自身改变 //r=&y;NO //*r=*r+1;NO //x++;YES 三、对于类型检查 可以把非const对象赋予const指针,这样就不能改变.但是不能把const赋给非const,除非先强制转换 const int x=100; int *p=(int*)&x; *p++; 四、对于函数 1.void Fuction1(const int r); //此处为参数传递const值,意义是变量初值不能被函数改变 2.const int Fuction1 (int); //此处返回const值,意思指返回的原函数里的变量的初值不能被修改,但是函数按值返回的这个变量被制成副本,能不能被修改就没有了意义,它可以被赋给任何的const或非const类型变量,完全不需要加上这个const关键字。 3.Class CX; //内部有构造函数,声明如CX(int r =0) CX Fuction1 () { return CX(); } const CX Fuction2 () { return CX(); } Fuction1() = CX(1); //没有问题,可以作为左值调用 Fuction2() = CX(1); //编译错误,const返回值禁止作为左值调用。 4.函数中指针的const传递和返回: int F1 (const char *pstr); //作为传递的时候使用const修饰可以保证不会通过这个指针来修改传递参数的初值 const char *F2();//意义是函数返回的指针指向的对象是一个const对象,它必须赋给一个同样是指向const对象的指针 const char * const F3(); //比上面多了一个const,这个const的意义只是在他被用作左值时有效,它表明了这个指针除了指向const对象外,它本身也不能被修改,所以就不能当作左值来处理。 五、对于类 1.首先,对于const的成员变量,只能在构造函数里使用初始化成员列表来初始化,试图在构造函数体内进行初始化const成员变量会引起编译错误。初始化成员列表形如:X:: X ( int ir ): r(ir) {} //假设r是类X的const成员变量 注意:类的构造和析构函数都不能是const函数。 2.建立了一个const成员函数,但仍然想用这个函数改变对象内部的数据。(函数不能修改类的数据成员)

c语言if的用法 条件condition可以是任何返回布尔值的表达式。 else子句是可选的。 if语句的执行过程如下:如果条件为真,就执行if的对象(statement1);否则,执行else的对象(statement2)。 任何时候两条语句都不可能同时执行。 考虑下面的例子:int a,b;if(a 任何情况下都不可能使a和b 都被赋值为0。 记住,直接跟在if 或else语句后的语句只能有一句。 如果你想包含更多的语句,你需要建一个程序块,如下面的例子:int bytesAvailable;if (bytesAvailable > 0) {ProcessData();bytesAvailable -= n;} elsewaitForMoreData();这里,如果变量bytesAvailable 大于0,则if 块内的所有语句都会执行。 嵌套if 语句嵌套(nested)if语句是指该if语句为另一个if或者else语句的对象。 在编程时经常要用到嵌套if语句。 当你使用嵌套if语句时,需记住的要点就是:一个else语句总是对应着和它同一个块中的最近的if语句,而且该if语句没有与其他else 语句相关联。 下面是一个例子:if(i == 10) {if(j 100) c = d; // this if iselse a = c; // associated with this else}else a = d; // this else refers to if(i ==

10)如注释所示,最后一个else语句没有与if(j 最后一个else语句对应着if(i==10)。 内部的else语句对应着if(k>100),因为它是同一个块中最近的if 语句。 if-else-if 阶梯基于嵌套if语句的通用编程结构被称为if-else-if 阶梯。 它的语法如下:if(condition)statement;else if(condition)statement;else if(condition)statement;elsestatement;条件表达式从上到下被求值。 一旦找到为真的条件,就执行与它关联的语句,该阶梯的其他部分就被忽略了。 如果所有的条件都不为真,则执行最后的else语句。 最后的else语句经常被作为默认的条件,即如果所有其他条件测试失败,就执行最后的else语句。 如果没有最后的else语句,而且所有其他的条件都失败,那程序就不做任何动作。 . 下面的程序通过使用if-else-if阶梯来确定某个月是什么季节。 // Demonstrate if-else-if statements.main() {int month = 4; // Aprilif (month == 12 || month == 1 || month == 2)printf ( "Winter");else if (month == 3 || month == 4 || month == 5)printf ("Spring");else if (month == 6 || month == 7 || month == 8)printf ( "Summer");else if (month == 9

const是一个C语言的关键字,它限定一个变量不允许被改变。使用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位于*的右侧,const就是修饰指针本身,即指针本身是常量。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。

c语言i f语句的练习题答 案 Prepared on 24 November 2020

1、编写程序输入a和b,求a和b的余数和商。 #include<> voidmain() { inta,b; scanf("%d%d",&a,&b); printf("商为%d余数为%d",a/b,a%b); } 2、输入一个整型数据,分别求出各位数字。如:469,则个位数是9,十位数 是6,百位数是4。 #include<> voidmain() {inta,m=0; intt,t1,t2,t3,t4; scanf("%d",&a); if(a<0||a>99999) printf("输入数据超出范围\n"); elseif(a>=0&&a<10) {m=1; printf("该数是%d位数,其个位数为%d\n",m,a); } elseif(a>=10&&a<100) { m=2; t=a%10; a=a/10; printf("该数是%d位数,其个位数为%d十位数为%d\n",m,t,a); } elseif(a>=100&&a<1000) { m=3; t=a%10; t1=(a/10)%10; t2=a/100; printf("该数是%d位数,其个位数为%d十位数为%d百位数为%d\n",m,t,t1,t2);

elseif(a>=1000&&a<10000) { m=4; t=a%10; t1=a/10%10; t2=a/100%10; t3=a/1000; printf("该数是%d位数,其个位数为%d十位数为%d百位数为%d千位数字 为%d\n",m,t,t1,t2,t3); } elseif(a>=10000&&a<100000) { m=5; t=a%10; t1=a/10%10; t2=a/100%10; t3=a/1000%10; t4=a/10000; printf("该数是%d位数,其个位数为%d十位数为%d百位数为%d千位数字为%d 万位数字为%d\n",m,t,t1,t2,t3,t4); } } 以上写法太繁琐了,如果学习了循环,则简单很多。 #include<> voidmain() { inta,b; intn=0; scanf("%d",&a); while(a)//while(a!=0) {n++;//n用来统计数字a是几位数,n的初值必须为0 b=a%10; a=a/10;//a/=10; printf("%d",b);//输出a的各位数字 } printf("a的位数为%d",n);//此语句必须写在循环体的外面

或许还有不少人对于const修饰符理解的并不深刻,都只是停留在一个比较浅的层面上,仅仅是在读别人代码的时候看到了const修饰符的使用,自己的写代码的过中从未使用过,所以自然对于const修饰符比较陌生。那么到底什么是const 修饰符,我们在自己编写C语言代码的过程中又该如何有效的使用const修饰符呢,现在让我们来学习下const修饰符的使用。 const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,即就是说其所修饰的对象为常量。当你代码中想要设法阻止一个变量被改变,那么这个时候可以选择使用const关键字。在你给一个变量加上const修饰符的同时,通常需要对它进行初始化,在之后的程序中就不能再去改变它。 可能有的人会有一个疑问,我们不是有在C中有预处理指令#define VariableNameVariableValue可以很方便地进行值替代,干嘛还要引入const修饰符呢?!这是因为预处理语句虽然可以很方便的进行值得替代,但它有个比较致命的缺点,即预处理语句仅仅只是简单值替代,缺乏类型的检测机制。这样预处理语句就不能享受C编译器严格类型检查的好处,正是由于这样,使得它的使用存在着一系列的隐患和局限性。 在讲解const修饰符之前,我们在此首先给出const修饰符的几个典型作用: 1. const类型定义:指明变量或对象的值是不能被更新,引入目的是为了取代预编译指令 2. 可以保护被修饰的东西,防止意外的修改,增强程序的健壮性; 3. 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。 4. 可以节省空间,避免不必要的内存分配。 接下来看看具体的使用。 一、const修饰符在函数体内修饰局部变量。 constint n=5; 和 intconst n=5;

1.const的用法: 看到const 关键字,C++程序员首先想到的可能是const 常量。这可不是良好的条件反射。如果只知道用const 定义常量,那么相当于把火药仅用于制作鞭炮。const 更大的魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。 const 是constant 的缩写,“恒定不变”的意思。被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多C++程序设计书籍建议:“Use const whenever you need”。 1.用const 修饰函数的参数 如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。const 只能修饰输入参数: 如果输入参数采用“指针传递”,那么加const 修饰可以防止意外地改动该指针,起到保护作用。 例如StringCopy 函数: void StringCopy(char *strDestination, const char *strSource); 其中strSource 是输入参数,strDestination 是输出参数。给strSource 加上const修饰后,如果函数体内的语句试图改动strSource 的内容,编译器将指出错误。 如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。 例如不要将函数void Func1(int x) 写成void Func1(const int x)。 同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A 为用户自定义的数据类型。 对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。 为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void Func(A & a) 存在一个缺点: “引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)。 以此类推,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。 问题是如此的缠绵,我只好将“const &”修饰输入参数的用法总结一下。 对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。 对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。

1、C中的CONST CONST const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的安全性和可靠性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。另外CONST在其他编程语言中也有出现,如C++、PHP5、C#.net、HC08 C。 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;

In my last column, I discussed one of the reasons why the rules by which a compiler can place data into ROM are a bit more complicated in C++ than they are in C.1I have more to say about that subject, but before I do, I’d like to reply to the following query I received through e-mail from Phil Baurer at Komatsu Mining Systems: “We’re having an interesting prob-lem using const with a typedef. I hoped you could comment on this sit-uation. I am wondering if we are bumping into some unknown (by us) rule of the C language. “We are using the Hitachi C com-piler for the Hitachi SH-2 32-bit RISC microcontroller. We thought the fol-lowing code: t y p e d e f v o i d*V P; c o ns t V P v e c t o r T a b l e[] ={....};(1) should be identical to: c o ns t v o i d*v e c t o r T a b l e[] ={....};(2)“However, the linker places v e c t o r T a b l e in (1) into the C O N S T A N T section, but it places v e c t o r T a b l e in (2) into the D A T A section. “Is this the proper behavior or a bug in the compiler?” This is proper behavior; it is not a bug. You are indeed bumping into some rules of the C language that you apparently don’t know about. Don’t feel bad; you’re not alone. I believe many other C and C++ pro- grammers are confused about these rules, which is why I’m answering this in my column. I presented some of these rules in an earlier column.2However, in look- ing back at that column, I don’t think I emphasized strongly enough the points which seem to be the source of your confusion. So let me try again. Declarat ors Here’s the first insight: Every declaration in C and C++ has two principal parts: a sequence of zero or more declaration specifiers, and a sequence of one or more declarators, separated by commas. For example: A declarator is the name being declared, possibly surrounded by operators such as *, [], (), and (in the case of C++) &. As you already know, the symbol *in a declarator means “pointer to” and []means “array of.” Thus, *x[N]is a declarator indicating that x is an “array of N elements of pointer to ...” something, where that something is the type specified in the declaration specifiers. For example, s t a t i c u ns i g ne d l o ng i nt*x[N]; declares x as an object of type “array of N elements of pointer to unsigned long int.” (As explained later, the key- word s t a t i c does not contribute to the type.) How did I know that *x[N]is an “array of ... pointer to ...” rather than a “pointer to an array of ...?” It follows from this rule: The operators in a declarator group accord- ing to the same precedence as they do when they appear in an expression. For example, if you check the near- est precedence chart for either C or C++, you’ll see that []has higher precedence than *. Thus the declara- tor *x[N]means that x is an array before it’s a pointer. Parentheses serve two roles in declarators: first, as the function call operator, and second, as grouping. As the function call operator, ()have the same precedence as []. As grouping, ()have the highest precedence of all. Embedded Systems Programming FEBRUARY 1999 13 Dan Saks const T vs.T const Although C and C++ read mostly from top-to- bottom and left-to-right, pointer declarations read, in a sense, backwards.

下面这几个宏是为了进行条件编译。一般情况下源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。 条件编译命令最常见的形式为: #ifdef 标识符 程序段1 #else 程序段2 #endif 它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。 其中#else部分也可以没有,即: #ifdef 程序段1 #denif 这里的“程序段”可以是语句组,也可以是命令行。这种条件编译可以提高C源程序的通用性。如果一个C源程序在不同计算机系统上运行,而不同的计算机又有一定的差异。例如,我们有一个数据类型,在Windows平台中,应该使用long类型表示,而在其他平台应该使用float表示,这样往往需要对源程序作必要的修改,这就降低了程序的通用性。可以用以下的条件编译: #ifdef WINDOWS #define MYTYPE long #else #define MYTYPE float #endif 如果在Windows上编译程序,则可以在程序的开始加上 #define WINDOWS 这样则编译下面的命令行: #define MYTYPE long 如果在这组条件编译命令之前曾出现以下命令行: #define WINDOWS 0 则预编译后程序中的MYTYPE都用float代替。这样,源程序可以不必作任何修改就可以用于不同类型的计算机系统。当然以上介绍的只是一种简单的情况,可以根据此思路设计出其它的条件编译。 例如,在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:

const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable)。 1、函数体内修饰局部变量。 例: void func(){ const int a=0; } 首先,我们先把const这个单词忽略不看,那么a是一个int类型的局部自动变量,我们给它赋予初始值0。 然后再看const. const作为一个类型限定词,和int有相同的地位。 const int a; int const a; 是等价的。于是此处我们一定要清晰的明白,const修饰的对象是谁,是a,和int没有关系。const 要求他所修饰的对象为常量,不可被改变,不可被赋值,不可作为左值(l-value)。 这样的写法也是错误的。 const int a; a=0; 这是一个很常见的使用方式: const double pi=3.14; 在程序的后面如果企图对pi再次赋值或者修改就会出错。 然后看一个稍微复杂的例子。 const int* p; 还是先去掉const 修饰符号。 注意,下面两个是等价的。 int* p; int *p; 其实我们想要说的是,*p是int类型。那么显然,p就是指向int的指针。 同理 const int* p; 其实等价于

const int (*p); int const (*p); 即,*p是常量。也就是说,p指向的数据是常量。 于是 p+=8; //合法 *p=3; //非法,p指向的数据是常量。 那么如何声明一个自身是常量指针呢?方法是让const尽可能的靠近p; int* const p; const右面只有p,显然,它修饰的是p,说明p不可被更改。然后把const去掉,可以看出p是一个指向int形式变量的指针。 于是 p+=8; //非法 *p=3; //合法 再看一个更复杂的例子,它是上面二者的综合 const int* const p; 说明p自己是常量,且p指向的变量也是常量。 于是 p+=8; //非法 *p=3; //非法 const 还有一个作用就是用于修饰常量静态字符串。 例如: const char* name="David"; 如果没有const,我们可能会在后面有意无意的写name[4]='x'这样的语句,这样会导致对只读内存区域的赋值,然后程序会立刻异常终止。有了const,这个错误就 能在程序被编译的时候就立即检查出来,这就是const的好处。让逻辑错误在编译 期被发现。 const 还可以用来修饰数组 const char s[]="David"; 与上面有类似的作用。 2、在函数声明时修饰参数 来看实际中的一个例子。 NAME

C语言中,if是一个条件语句,用法 if(条件表达式) 语句 如果满足括号里面表达式,表示逻辑为真于是执行后面的语句,否则不执行(表达式为真则此表达式的值不为0,为假则为0,也就是说,如果括号里面不是一个判断表达式,你填了一个不是0的数字或其他,表示条件永远为真,一定执行后面的语句,反之,你填了一个0,则永远不会执行后面的语句)。 if后面的语句如果多于一句,可以放在{}里面作为复合语句, 例: int a=2,b=1; if(a>b) cout<<"a>b"<1 ,表达式a>b为真,于是执行后面的语句,输出a>b 这几个字符。 goto 是转向语句,按其英文含义就可理解 用法标号:语句; ...................... goto 标号; 或者 goto 标号; ..................... 标号:语句; 标号和goto必须包括处于同一个函数内标号的写法跟变量名一样不能和关键词相同,后面必须带冒号 当程序执行到goto这个语句时,程序就转跳到标号后面的语句去了 例 int x=1; biaohao: x=x+1; if(x<100) goto biaohao; cout<<"x=100"<

C中goto语句的用法 个人觉得goto用在内层循环中比较合适,用break只能跳出内层循环,而goto可以直接跳出最外层循环,在合理的地方使用就可以了。debian:/home/server# vi goto.c #include #include int main() { int i, j; for (j = 0; j < 3; j++) { for (i = 0; i < 10; i++) { printf("j: %d, i: %d\n", j, i); if (i == 3) goto last; } } last: printf("This is the last line\n"); return 0; } debian:/home/server# gcc -o goto goto.c

一总述 我们的压力专家在三十多年研制和生产活塞压力计的基础上,利用国外新技术、新材料使我公司研制、生产出的压力校验器能更好地满足用户校验压力仪器、仪表时使用。因此,便携、省力、使用方便、密封性能好和易维护正是我公司压力校验器的特点。我公司还参与起草了机械部标准:JB/T599《压力表校验器》。我公司的多项专利技术均处于国际先进水平。 压力校验器是压力校验系统的重要组成设备,密封性是压力校验器的最重要指标。经过与国外同类产品比较,本公司的压力校验器在密封性、造压的轻便性和微量调节性能等方面处于同类产品的领先地位。本公司的压力校验器特别考虑了微压受温度影响问题,高压压力校验器针对高压被检压力仪表回检时不能平稳降压的问题,我们做出了很好的解决方案。 压力校验器的研制,参照了有关标准,如机械部标准:JB/T599《压力表校验器》、JB/T 7393-1994《活塞式压力计》及国家标准:GB/T 14211-93《机械密封试验方法》,并且参考了有关国家计量检定规程:JJG 129-90《一等标准活塞式压力计检定规程》、JJG 49-1999《弹簧管式精密压力表及真空表检定规程》、JJG 52-1999《弹簧管式一般压力表、压力真空表及真空表检定规程》。

我公司的液体压力泵的密封性优于国家标准五倍以上。本公司的气体压力泵的密封性优于国家标准十倍以上。 活塞与压力校验器组成压力测试系统,是动态平衡系统。在活塞有效行程内,系统压力不变,现象是压力稳定。数字压力校验仪与压力校验器组成的压力测试系统是密闭非动态平衡系统。加压过程中,由于压缩原因,分子需吸收能量,分子间隙缓慢减小,所以压力不会立即稳定(表现为压力下降、系统不稳),需等待一段时间压力才会稳定。降压过程中,由于膨胀原因,分子需释放能量,分子间隙增大,所以压力不会立即稳定(表现压力上升、系统不稳),需等待一段时间压力才会稳定。 上述二种现象,只是物理过程不同,该现象在液体压力校验器与数字压力校验仪组成的系统中表现尤其明显。 本公司压力校验器的研制充分考虑了国内被检压力仪表的实际状况,压力校验器具有防尘、过滤功能,维护极其方便。 国家标准对密封性试验的主要要求:压力校验器在加压10分钟后开始计时,5分钟内压力校验器的泄漏量不得超过满量程的5%。 国家检定规程对密封性试验的主要要求:压力校验器在加压5分钟后开始计时,5分钟内压力校验器的泄漏量不得超过满量程的4%。

C语言选择语句 C语言支持两种选择语句:if语句和switch语句。这些语句允许你只有在程序运行时才能。知道其状态的情况下,控制程序的执行过程。首先看一下if语句的用法: if语句: if语句是c语言中的条件分支语句。它能将程序的执行路径分为两条。if语句的完整格式如下: if (condition) statement1;; else statement2; 其中,if和else的对象都是单个语句(statement),也可以是程序块。条件condition可以是任何返回布尔值的表达式。else子句是可选的。 if语句的执行过程如下:如果条件为真,就执行if的对象(statement1);否则,执行else的对象(statement2)。任何时候两条语句都不可能同时执行。考虑下面的例子: int a,b; if(a < b) a = 0; else b = 0; 本例中,如果a小于b,那么a被赋值为0;否则,b被赋值为0。任何情况下都不可能使a 和b都被赋值为0。 记住,直接跟在if 或else语句后的语句只能有一句。如果你想包

含更多的语句,你需 要建一个程序块,如下面的例子: int bytesAvailable; if (bytesAvailable > 0) { ProcessData(); bytesAvailable -= n; } else waitForMoreData(); 这里,如果变量bytesAvailable 大于0,则if块内的所有语句都会执行。 嵌套if 语句 嵌套(nested)if语句是指该if语句为另一个if或者else语句的对象。在编程时经常要用到嵌套if语句。当你使用嵌套if语句时,需记住的要点就是:一个else语句总是对应着和它同一个块中的最近的if语句,而且该if语句没有与其他else语句相关联。下面是一个例子:if(i == 10) { if(j < 20) a = b; if(k > 100) c = d; // this if is else a = c; // associated with this else } else a = d; // this else refers to if(i == 10) 如注释所示,最后一个else语句没有与if(j <20)相对应,因为它

相关主题