‘壹’ C语言中 int a=1 printf(“%f”,a) 输出的为什么是0 不是1.0呢
printf 的参数并不会自动做类型转换的。
例子中格式串中有“%f”,编译器就会当后边的参数是个浮点数,它不做类型检查。
而把一个 int当成浮点数,因为两种类型的存储结构是完全不同的,后果就难以预料了,有可能程序崩溃,也可能正常运行,但得不到正确的结果。
具体到楼主这个问题, 把整数1当成浮点数处理,那就是符号位0,阶码0,尾数1,是非规范浮点数,不同编译器处理结果可能不同。 所以,不要写出这样的代码。
‘贰’ 一个C语言尝试
C语言中虽然有变量隐含类型转换机制,但也是有一定使用范围的。对于printf这类不定参数函数,编译器是不做参数类型检查的,因此就不会知道参数应该是什么类型,更不可能去做类型转换了。
int(100.5)=100
‘叁’ c语言吧。为什么输出会是1,而不是0.
printf
的参数并不会自动做类型转换的。
例子中格式串中有“%f”,编译器就会当后边的参数是个浮点数,它不做类型检查。
而把一个
int当成浮点数,因为两种类型的存储结构是完全不同的,后果就难以预料了,有可能程序崩溃,也可能正常运行,但得不到正确的结果。
具体到楼主这个问题,
把整数1当成浮点数处理,那就是符号位0,阶码0,尾数1,是非规范浮点数,不同编译器处理结果可能不同。
所以,不要写出这样的代码。
‘肆’ C++静态代码检查工具
PC Lint被称为C / c++的PC - Lint / FlexeLint。它是由GIMPEL软件开发的C / c++静态代码检测工具,由许多大型软件公司的程序员使用。
我们知道,许多用户从事开发C / c++编程语言,其语法没有其他语言的灵活性,这种灵活性使促进代码的效率,但由于C / c++编译器不是强制性的类型检查,不做任何边境检查,这就增加了代码中存在的隐患的可能性。PC Lint,这个软件的重点是对代码的逻辑分析,它可以在潜在错误的代码中找到,比如数组访问跨界、内存泄漏、使用未初始化的变量等,用于检测编译器无法检测到的bug通常类型。
PC lint几乎支持所有流行的编辑器和编译器环境,例如Borland c++从1到5。xx版本,Borland c++构建,GCC,VC,watcomC / c++,insight的来源,intelC / c++,等等,也支持16 /32/ 64平台环境。
所示。支持Scott Meyes的经典(有效的c++ /更有效的c++),各种提高效率和防止错误的方法。
‘伍’ 对于C++语言来说,什么叫做类型检查
静态检查:书中对静态检查的阐述:“编译器必须检查源程序是否符合源语言规定的语法和语义要求。”由此看来,静态检查其实就是语义分析了。
类型系统:
类型错误:将int赋给一个指针就是类型错误。
类型检查:检查类型错误,属于静态检查的一部分,编译器实现可能有两种情况:第一种是将中间代码生成、类型检查放到语法分析一起做,完成语法分析的同时进行语义分析。对于某些复杂的结构,则将类型检查作为语法分析和中间代码生成之间单独的一遍。
强类型语言:某语言的编译器保证所接受的程序不会在运行时发生“类型错误”,则此语言是强类型语言。
类型安全语言:将int赋给一个指针,C/C++会编译器会抱错,于是C/C++称为类型安全语言.。似乎“类新安全”和“强类型”本质上一样。
‘陆’ c语言中所调用的函数实参和形参类型不一致该怎么办是以谁为准,还是直接编译报错
编译器在编译时默认会做类型检查,发现行参与实参类型不一致时会提示编译警告,如果确认赋值调用不存在赋值不兼容,且不会发生溢值现象,可以使用强制类型转换,跳开编译警告。此外,可以也在编译选项中取消类型检查。
‘柒’ 类型系统的类型检查
类型检查所进行的检验处理以及实行类型的约束,可发生在编译时期(静态检查)或运行时期(动态检查)。静态类型检查是在编译器所进行语义分析中进行的。如果一个语言强制实行类型规则(即通常只允许以不丢失信息为前提的自动类型转换)就称此处理为强类型,反之称为弱类型。 如果一个编程语言的类型检查,可在不测试运行时期表达式的等价性的情况下进行,该语言即为静态类型的。一个静态类型的编程语言,是在运行时期和编译时期之间的处理阶段下重视这些区别的。如果程序的独立模块,可进行各自的类型检查(独立编译),而无须所有会在运行时出现的模块的那些信息,该语言即具有一个编译时期阶段。如果一个编程语言支持运行时期(动态)调度已标记的数据,该语言即为动态类型的。如果一个编程语言破坏了阶段的区别,因而类型检查需要测试运行时期的表达式的等价性,该语言即为依存类型的。
在动态类型中,经常在运行时期进行类型标记的检查,因为变量所约束的值,可经由运行路径获得不同的标记。在静态类型编程语言中,类型标记使用辨识联合类型表示。
动态类型经常出现于脚本语言和RAD语言中。动态类型在解译语言中极为普遍,编译语言则偏好无须运行时期标记的静态类型。对于类型和隐式类型语言较完整的列表参见类型和隐式类型语言。
术语推断类型(鸭子类型,ck typing)指的是动态类型在语言中的应用方式,它会“推断”一个数值的类型。
某些静态语言有一个“后门”,在这些编程语言中,能够编写一些不被静态类型所检查的代码。例如,Java 和 C-风格的语言有“转型”可用。在静态类型的编程语言中,不必然意味着缺乏动态类型机制。例如 Java 使用静态类型,但某些运算需要支持运行时期的类型测试,这就是动态类型的一种形式。更多静态和动态类型的讨论,请参阅编程语言。 对静态类型和动态类型两者之间的权衡也是必要的。
静态类型在编译时期时,就能可靠地发现类型错误。因此通常能增进最终程序的可靠性。然而,有多少的类型错误发生,以及有多少比例的错误能被静态类型所捕捉,仍有争论。静态类型的拥护者认为,当程序通过类型检查时,它才有更高的可靠性。虽然动态类型的拥护者指出,实际流通的软件证明,两者在可靠性上并没有多大差别。可以认为静态类型的价值,在于增进类型系统的强化。强类型语言(如 ML 和 Haskell)的拥护者提出,几乎所有的臭虫都可以看作是类型错误,如果编写者以足够恰当的方式,或者由编译器推断来声明一个类型。
静态类型通常可以编译出速度较快的代码。当编译器清楚知道所要使用的数据类型,就可以产生优化过后的机器码。更进一步,静态类型语言中的编译器,可以更轻易地发现较佳捷径。某些动态语言(如 Common Lisp)允许任意类型的声明,以便于优化。以上理由使静态类型更为普及。参阅优化。
相较之下,动态类型允许编译器和解译器更快速的运作。因为源代码在动态类型语言中,变更为减少进行检查,并减少解析代码。这也可减少编辑-编译-测试-除错的周期。
静态类型语言缺少类型推断(如 Java),而需要编写者声明所要使用的方法或函数的类型。编译器将不允许编写者忽略,这可为程序起附加性说明文件的作用。但静态类型语言也可以无须类型声明,所以与其说是静态类型的代价,倒不如说是类型声明的报酬。
静态类型允许构造函数库,它们的用户不太可能意外的误用。这可作为传达库开发者意图的额外机制。
动态类型允许建构一些静态类型系统所做不出来的东西。例如,eval 函数,它使得运行任意数据作为代码成为可能(不过其代码的类型仍是静态的)。此外,动态类型容纳过渡代码和原型设计,如允许使用字符串代替数据结构。静态类型语言最近的增强(如 Haskell 一般化代数数据类型)允许 eval 函数以类型安全的方式撰写。
动态类型使元程序设计更为强大,且更易于使用。例如 C++ 模板的写法,比起等价的 Ruby 或 Python 写法要来的麻烦。更高度的运行时期构成物,如元类型(metaclass)和内观(Introspection),对静态类型语言而言通常更为困难。
‘捌’ c++ #define 和 const 有什么区别
(1)
编译器处理方式不同
define宏是在预处理阶段展开。
const常量是编译运行阶段使用。
(2)
类型和安全检查不同
define宏没有类型,不做任何类型检查,仅仅是展开。
const常量有具体的类型,在编译阶段会执行类型检查。
(3)
存储方式不同
define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
const常量会在内存中分配(可以是堆中也可以是栈中)。
(4)const
可以节省空间,避免不必要的内存分配。
例如:
#define
PI
3.14159
//常量宏
const
doulbe
Pi=3.14159;
//此时并未将Pi放入ROM中
......
double
i=Pi;
//此时为Pi分配内存,以后不再分配!
double
I=PI;
//编译期间进行宏替换,分配内存
double
j=Pi;
//没有内存分配
double
J=PI;
//再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而
#define定义的常量在内存中有若干个拷贝。
(5)
提高了效率。
编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
‘玖’ C++编程中const和#define的区别
(1) 编译器处理方式不同
define宏是在预处理阶段展开。
const常量是编译运行阶段使用。
(2) 类型和安全检查不同
define宏没有类型,不做任何类型检查,仅仅是展开。
const常量有具体的类型,在编译阶段会执行类型检查。
(3) 存储方式不同
define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
const常量会在内存中分配(可以是堆中也可以是栈中)。
(4)const 可以节省空间,避免不必要的内存分配。 例如:
#define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ......
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而 #define定义的常量在内存中有若干个拷贝。
(5) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
‘拾’ void main与void main(void) 有什么不一样
你是想问
void main() 与 void main(void)
的区别吧?
若是在C++里,没有区别,但是,对于早期C程序的函数而言,声明的参数列表为空或者void,都是一个意思——参数任意!也就是说,你可以像该函数传递任何参数,编译器不做类型检查!某些情况下,这是非常危险的。因此,在C++里,编译器对此的解释就是:该函数没有任何参数!如果你像该函数传递参数,编译器会报错。
举个例子:
C中:
void fun(void);
调用时,你可以传递任何参数;例如:
int a; float f; char c;
fun(a); fun(f); fun(c);
都是对的。因为编译器不会检查该函数的参数都是什么。
C++中:你只能这么调用该函数:
fun();
不能有任何参数!
char option = '\0'
是定义一个char类型的变量option,并初始化为'\0'字符,\0是一个完整的字符,多用于字符串处理中,代表字符串的结束,例如,你以一个char型数组储存字符串,编译器会自动在末尾补以'\0'字符,以示字符串的结束。比如:
char buffer[] = "abcd";
实际上buffer数组是这个样子:
'a''b''c''d''\0'
分别对应buffer[0],buffer[1],...,buffer[4]
有4+1=5个元素。