C语言学习笔记--C常量

C常量

常量是固定值,在程序执行期间不会改变。这些固定值,又叫字面量
常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量、或字符串字面值,也有枚举常量。
常量就像是常规的变量,只不过常量的值在定义后不能进行修改。

整数常量

整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x或0X表示十六进制,0表示八进制,不带前缀则默认表示十进制。
整数常量也可以带一个后缀,后缀是U和L的组合,U表示无符号整数,L表示长整数。后缀可以是大写,也可以是小写,U和L的顺序任意。
下面列举几个整数常量的实例:

212		//合法的
215u	//合法的
0xFeeL	//合法的
078		//非法的:8不是八进制数字
032UU	//非法的:不能重复后缀

以下是各种类型的整数常量的实例:

85		//十进制
0213	//八进制
0x4b	//十六进制
30		//整数
30u		//无符号整数
30l		//长整数
30ul	//无符号长整数

浮点常量

浮点常量有整数部分、小数点、小数部分和指数部分组成。可以使用小数形式或者指数形式来表示浮点常量。
当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时,必须包含小数点、指数,或同时包含两者。带符号的指数使用e或E引入的。
下面列举几个浮点常量的实例:

3.14159		//合法的
314159E-5L	//合法的
510E		//非法的:不完整的指数
210f		//非法的:没有小数或指数
.e55		//非法的:缺少整数或分数

字符常量

字符常量是括在单引号中,例如,‘X’可以存储在char类型的简单变量中。
字符变量可以是一个普通的字符(例如‘X’)、一个转义序列(例如‘\t’),或一个通用的字符(例如‘\u02C0’)或制表符(\t)等。下标列出了一些这样的转义序列码:

转义序列含义
\\\字符
\’'字符
\""字符
\??字符
\a警报铃声
\b退格键
\f换页符
\n换行符
\r回车
\t水平制表符
\v垂直制表符
\ooo一到三位的八进制数
\xhh…一个或多个数字的十六进制数

下面的实例显示了一些转义序列字符:
实例

#include<stdio.h>
int main()
{
	printf("Hello\tWorld\n\n");
	return 0;
}

当上面的代码被编译和执行时,会产生下列结果:

Hello   World

字符串常量

字符串字面值或常量是括在双引号" "中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
可以使用空格做分隔符,把一个很长的字符串常量进行分行。
下面的实例显示了一些字符串常量。下面这三种形式所显示的字符串是相同的。

"hello,dear"
"hello,\
dear"
"hello," "d" "ear"

定义常量

在C中,有两种简单的定义常量的方式:

  1. 使用#define预处理器。
  2. 使用const关键字。
    #define预处理器
    下面是使用#define预处理器定义常量的形式:
#define identifier value

具体请看下面的实例:
实例

#include <stdio.h>
 
#define LENGTH 10   
#define WIDTH  5
#define NEWLINE '\n'
 
int main()
{
 
   int area;  
  
   area = LENGTH * WIDTH;
   printf("value of area : %d", area);
   printf("%c", NEWLINE);
 
   return 0;
}

上面代码被编译和执行时,他会产生下列结果:

value of area:50

const关键字
可以使用const前缀声明制定类型的常量,如下所示:

const type variable=value;

具体请看下面的实例:
实例

#include <stdio.h>
 
int main()
{
   const int  LENGTH = 10;
   const int  WIDTH  = 5;
   const char NEWLINE = '\n';
   int area;  
   
   area = LENGTH * WIDTH;
   printf("value of area : %d", area);
   printf("%c", NEWLINE);
 
   return 0;
}

当上面的代码被编译和执行时,会产生下列结果:

value of area:50

请注意,把常量定义为大写字母形式,是一个很好的编程实践。
注意#define是宏定义,他不能定义常量,单宏定义可以实现在字面意义上和其他定义常量相同的功能,本质的区别就在于 #define 不为宏名分配内存,而const也不为常量分配内存,因为const并不是去定义一个常量,而是去改变一个变量的存储类,把该变量所占的内存变为只读。
const定义的是变量不是常量,只是这个变量的值不允许改变是常变量!带有类型。编译运行的时候起作用存在类型检查。
define定义的是不带类型的常数,只进行简单的字符替换。在预编译的时候起作用,不存在类型检查。
1、#define与const两者的区别
(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)宏替换只作替换,不做计算,不做表达式求解,宏预编译时就替换了,程序运行时,并不分配内存。
注意:define有边缘效应,例:#define N 2+3,N的值是5。

int a=N/2

在编译是预想a=2.5,实际打印结果是3.5,原因是在预处理阶段,编译器将a=N/2处理成a=2+3/2,这就是define宏的边缘效应,所以我们应该写成 #define N(2+3)

#include <stdio.h>

#define LENGTH 10+10
//正确写法 #define LENGTH (10+10)
#define WIDTH  5
#define NEWLINE '\n'
int main(){   
    int area;   
    area = LENGTH * WIDTH;   
    printf("value of area : %d", area);   
    printf("%c", NEWLINE);   
    return 0;
}

以上实例输出结果:

value of area : 60

所以如果我们需要得到正确结果应该将 #define LENGTH 10+10修改为 #define LENGTH (10+10)

补充说明

单引号与双引号的区别:
在 C 语言中,单引号与双引号是有很大区别的。
在 C 语言中没有专门的字符串类型,因此双引号内的字符串会被存储到一个数组中,这个字符串代表指向这个数组起始字符的指针;而单引号中的内容是一个 char 类型,是一个字符,这个字符对应的是 ASCII 表中的序列值。

四种进制说明:
在二进制中只有 0、1 两种情况,你不会看到比 1 大的数字。二进制是逢 2 就进位,所有数字中没可能有 2 或大于 2 的数字。
在八进制中有 0、1、2、3、4、5、6、7这八种情况,你也不会看到比7大的数字。八进制是逢8就进位,所有数字中没可能有8或大于8的数字。
在十进制中有0、1、2、3、4、5、6、7、8、9这十种情况,你更不会看到比9大的数字。十进制是逢10就进位,所有数字中有0~9都有。
在十六进制中有 0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F,其中 A 表示 10;B 表示 11;C 表示 12;D 表示 13;E 表示 14;F 表示 15。十六进制数字中含有 A–F字母,它是 0–9+A–F

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值