常量是指在程序运行过程中不可改变的量,C语言中的数值都可以用常量来表示。常量可以表示各种数据类型的值。
总结一下在打印时,各种类型常量要替换的符号:
类型 | 所占字节数 | 表示范围 | 替换字符(printf) |
---|---|---|---|
char | 1 | -128~127 | %c |
unsigned char | 1 | 0~255 | %c |
short | 2 | -32768~32767 | %hd |
unsigned short | 2 | 0~65535 | %hu |
int | 2 | -32768~32767 | %d |
unsigned int | 2 | 0~65535 | %u |
long | 4 | -2147483648~2147483647 | %ld |
unsigned long | 4 | 0~4294967295 | %lu |
float | 4 | -3.4* 10-38 ~ 3.4* 1038 | %f |
double | 8 | -1.7E-308~1.7E+308 | %lf |
变量指在程序中可以改变的量,由变量名和变量值组成。变量名是一个标识符,变量值是一个数据值。
程序为每个变量都分配了一个存储空间,其数据值存储在该空间中,程序可以使用变量名来访问这个存储空间,通过读取和修改该空间的内容来实现访问和修改该变量。
声明变量的形式如下:
数据类型名 变量名
int year
double time
char flag
变量定义是一个完整的语句,是在运行期才能起作用的,而变量声明则在编译期就起作用。一般情况下,只要将变量定义语句放在使用语句之前即可。
如果要在变量定义语句之前使用变量,需要借助关键字extern来声明变量。
使用extern来声明变量的形式如下:
extern 数据类型名 变量名
extern int key
extern double score
范例1
#include
int main(void)
{
extern int data;
printf("data = %d\n",data);
return 0;
}
int data = 23;
赋值变量的形式如下:
变量名 = 值
int a; a = 2;
double b; b = 3.2;
以上幅值方式也可以这么写:
int a = 2;
double b = 3.2;
范例2
#include
int main(void)
{
int x = 2;
int y = 2;
int a,b,c = 3;
int i = 3, j = 3, k = 3;
printf("x = %-8d y = %-8d\n",x,y);//%-8d表示以8个数字为宽度进行左对齐
printf("a = %-8d b = %-8d c = %-8d\n",a,b,c);
printf("i = %-8d j = %-8d k = %-8d\n",i,j,k);
return 0;
}
这是由于只有c被幅值为2,变量a,b的值仍未被初始化,为不可知。
变量被定以后,都会占用一块内存,而内存都是有地址的。变量内存地址也可以直接成为变量的地址。
地址操作符(&)来获取变量的地址,指针操作符(*)来获取某地址上的内存内容。
地址操作符只能使用变量作为操作数。指针操作符必须为地址。
范例3
#include
int main(void){
int key = 0;
printf("Please input a integer: ");
scanf("%d",&key);
printf("key\t = %d\n",key);
printf("&key\t= %p\n",&key);
printf("*(&key)\t= %d\n",*(&key));
return 0;
}
//使用printf输出Copyright 2007-2008 ALU corporation.
# include
int main(void){
printf("Copyright 2007-2008 ALU corporation.\n");
printf("Copyright %d-%d ALU corporation.\n",2007,2008);
return 0;
}
//定义两个整型变量,分别使用scanf函数为他们赋值,并用printf输出
#include
int main(void){
int m = 0;
int n = 0;
printf("Please enter two integers:");
scanf("%d %d",&m,&n);
printf("The two numbers are %d %d",m,n);
return 0;
}
字节长度:short int < int < long int
sizeof函数可以得到数据类型所占空间,以字节为单位。
sizeof(数据类型)
范例1
#include
int main(void){
printf("sizeof(shor int) = %d\n",sizeof(short int));
printf("sizeof(int) = %d\n",sizeof(int));
printf("sizeof(long int) = %d\n",sizeof(long int));
printf("sizeof(long long int) = %d\n",sizeof(long long int));
return 0;
}
带signed前缀的数据类型和无符号修饰符的数据整型一样,而带unsigned修饰的数据类型表示非负数。
范例2
#include
int main(void){
/*定义多个变量以存储多个不同整型的数据*/
int int_dec,int_hex,int_oct; //定义三个int变量
int constant = 74; //定义并初始化变量
/*用三种进制形式给整型变量赋值*/
scanf("%d",&int_dec); //以十进制值形式为int_dec赋值
scanf("%x",&int_hex); //以十六进制值形式为int_hex赋值
scanf("%o",&int_oct); //以八进制值形式为int_oct赋值
/*用十进制的形式给整型变量赋值*/
printf("int_dec(11) = %d\n",int_dec); //打印十进制的11
printf("int_hex(11) = %d\n",int_hex); //打印十六进制的11
printf("int_oct(11) = %d\n",int_oct); //打印八进制的11
/*把十进制74用三种进制分别打印*/
printf("(Dec)74 = %d\n",constant); //输出74的十进制形式
printf("(Hex)74 = %x\n",constant); //输出74的十六进制小写形式
printf("(Hex)74 = %X\n",constant); //输出74的十六进制大写形式
printf("(Oct)74 = %o\n",constant); //输出74的八进制形式
return 0;
}
存储方式
整型按照存储方式和数值区间的不同,可分为两大类:有符号整型和无符号整型。其中,有符号整型在内存中的存储分为两部分,符号部分和数值部分。
**符号部分占1位:0为非负数,1为负数。**整型变量的数值以二进制值的形式存放在该部分中。其数值范围见最上面的表格。
转义字符表
ASCII码表
用整型数值赋值,整型数值会自动转化为相应的ASCII码赋值给字符变量。
char c1 = 97; //即’a’
范例3
#include
int main(void){
/*定义并初始化各种字符型变量*/
char c1 = '\n';
unsigned char c2 = '\t';
char c3 = 49;
printf("c1 = [%c],[%d]\n]",c1,c1); //输出c1的字符形式和ASCII码值
printf("c2 = [%c],[%d]\n]",c2,c2); //输出c2的字符形式和ASCII码值
printf("c3 = [%c],[%d]\n]",c3,c3); //输出c3的字符形式和ASCII码值
return 0;
}
%c时会表示其原始的含义,而%d会表示为其的ASCII码值。
字节长度:float< double <= long double
范例4
#include
int main(void){
printf("sizeof(float) = %d\n",sizeof(float));
printf("sizeof(double) = %d\n",sizeof(double));
printf("sizeof(long double) = %d\n",sizeof(long double));
return 0;
}
精度保留:%.+数字+替代符
例如保留小数点后7位,可以写为:%.7f。(float可以保留小数点后7位,double和long double可以保留小数点后16位)
存储方式
以科学技术法的表示形式存储在内存中。包含三部分:符号位,指数位,基数位
typedef
typedef语句又三个部分组成:关键字typedef、原数据类型名和新数据类型名。标准形式如下:
typedef 原数据类型 新数据类型
typedef char myChar; //给数据类型char起一个别名myChar
所有的新数据类型名只能单独组成数据类型,不能作为其他数据类型的一部分。
对于一些数据类型可能会改变的的变量,一般都用数据类型别名来命名。
为了提高程序可读性,经常将位数体现在重命名中。
例如:
typedef char int8_t;//把char型定义为int8,因为char有8位
typedef unsigned long uInt32_t;//把unsigned long型定义为uInt32,因为unsigned long有32位
把一个变量定义为const,意味着该变量的值将不会被改变;
把一个变量定义为volatile,意味着编译器不要对该变量优化。
const主要作用是定义只读变量。
const 数据类型名 变量名 = 初始值;
const int NUM_MONTH = 12;
在定义const时,必须要对该变量初始化,否则会报错。
大多数编译器不会为const变量分配内存空间,而是将它们保存在符号表中,提高程序效率。
volatile表示其修饰的变量随时可能变化,编译器每次优化时必须每次都重新读取这个变量的值。
volatile 数据类型名 变量名
volatile int data = 10;
在编写多线程的程序时,通过定义volatile,使得程序在读取该变量前会同步各个线程,以取得该变量的最新修改值。
练习1
//输入char型、int型和float型,再将其输出
#include
int main(void){
/*定义3个变量*/
char c_v = 0;
int i_v = 0;
float f_v = 0;
printf("Input a char number:");
scanf("%c",&c_v);
printf("Input a int number:");
scanf("%d",&i_v);
printf("Input a float number:");
scanf("%f",&f_v);
printf("c_v = [%c]\n",c_v);
printf("i_v = [%d]\n",i_v);
printf("f_v = [%f]\n",f_v);
return 0;
}
//设计一个程序,将输入的小写字母对应的大写字母输出
#include
int main(void){
char letter = 0;
printf("Input a lowerletter(a~z):");
scanf("%c",&letter);
printf("The capital is %c.\n",letter + 'A'-'a');
return 0;
}
//设计一个程序来验证浮点数的精度损失
#include
int main(void){
float n = 0.0;
n = 321654.32654;//有效数字超过8位,即将精度损失
if(n != 321654.32654)
printf("data lost\n");
return 0;
}