C语言入门:常量

#define 是宏定义,它不能定义常量,但宏定义可以实现在字面意义上和其它定义常量相同的功能,本质的区别就在于 #define 不为宏名分配内存,而 const 也不为常量分配内存,怎么回事呢,其实 const 并不是去定义一个常量,而是去改变一个变量的存储类,把该变量所占的内存变为只读!

反斜杠(\) 开头是叫转义序列(Escape Sequence)。

\ooo 是对用三位八进制数转义表示任意字符的形象化描述。

比如 char ch = '\101'; 等价于 char ch = 0101; (以0开头的表示八进制)。

\xhh 里面是 x 是固定的,表示十六进制(hexadecimal),h 也表示十六进制。

举例,char ch = '\x41'; 就是用十六进制来表示,它与前面的 \101 是等价的。

可用如下代码证明它们等价:

#include <stdio.h>
  
int main(){
    printf("%c,%c,%c,%c", 0101, '\101', '\x41', 'A');
    return 0;
}

const 定义的是变量不是常量,只是这个变量的值不允许改变是常变量!带有类型。编译运行的时候起作用存在类型检查。

define 定义的是不带类型的常数,只进行简单的字符替换。在预编译的时候起作用,不存在类型检查。

1、两者的区别

(1) 编译器处理方式不同

#define 宏是在预处理阶段展开。

const 常量是编译运行阶段使用。

(2) 类型和安全检查不同

#define 宏没有类型,不做任何类型检查,仅仅是展开。

const 常量有具体的类型,在编译阶段会执行类型检查。

(3) 存储方式不同

#define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。(宏定义不分配内存,变量定义分配内存。)

const常量会在内存中分配(可以是堆中也可以是栈中)。

(4) const 可以节省空间,避免不必要的内存分配。 例如:

#define NUM 3.14159 //常量宏
const doulbe Num = 3.14159; //此时并未将Pi放入ROM中 ......
double i = Num; //此时为Pi分配内存,以后不再分配!
double I= NUM; //编译期间进行宏替换,分配内存
double j = Num; //没有内存分配
double J = NUM; //再进行宏替换,又一次分配内存!

const 定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象 #define 一样给出的是立即数,所以,const 定义的常量在程序运行过程中只有一份拷贝(因为是全局的只读变量,存在静态区),而 #define 定义的常量在内存中有若干个拷贝。

(5) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

(6) 宏替换只作替换,不做计算,不做表达式求解;

宏预编译时就替换了,程序运行时,并不分配内存。

浮点型常数

1.十进制小数形式

它由数字0-9、小数点和+、-号组成,例如3。14、-23.56都是十进制小数

2.指数形式

它由数字0-9、字母e(或E)和+、-号组成,它的形式为aEn,意为a✖️10^n,其中a为十进制整数或小数,n为十进制整数。在表示浮点型畅常量时,需注意几点:

(1)以指数形式表示实数时,a和n都不能省略,n必须为整数。

(2)以十进制小数形式表示实数时,整数和小数部分可省略其中任一个

(3)浮点型常量默认是double型,如果在后面加上F或f,则其类型为float实数在机内是以指数形式存储的,以float类型为例,大多数C编译系统使用4个连续的字节(即32位)存储在float类型数据。这32位分为4个部分,最高位为数的符号,接着使用若干位存储小数的部分,然后是指数的符号位,最后一个部分是指数。在4个字节中,究竟小数部分和指数部分分别占多少位,ANSI C 本身并没有作规定,由具体的C语言编译系统自定。不少C语言编译系统用24位表示数符号和指数部分。

由实数的存储形式可看出,小数部分占的位数越多,所能表示的精度越高,指数部分占的越多,所能表示的数值范围越大。

正确理解 #define 的别名机制。

实例:

求 a 的值:

#include <stdio.h>
#define SQR(x) x*x

int main()
{
   /* 我的第一个 C 程序 */
   int a=16,k=2,m=1;
    a/=SQR(k+m)/SQR(k+m);
    printf("a=%d",a);
}

输出结果:

a=2

是不是跟我们想象的结果不太一样?

那么看一下你想象得结果:

#include <stdio.h>

int SQR(int x)
{
    return x*x;
}

int main()
{
   int a=16,k=2,m=1;
    a/=SQR(k+m)/SQR(k+m);
    printf("a=%d",a);
}

结果:

a=16

总结:#define 的声明 只是一个别名,并不会改变其内在逻辑,也就是不会自动加上小括号增加优先级。

附上其逻辑:

∵  SQR(x) x*x
又∵  a=16,k=2,m=1
∴SQR(k+m)/SQR(k+m)=2+1*2+1/2+1*2+1
∴原式=2+2+0.5+2+1
     =6+1.5
     =7.5
     =(int)7.5=7
故:a/=SQR(k+m)/SQR(k+m)  = a/7=16/7=2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰度少爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值