一、变量和常量
1. 常量
在程序运行过程中不可以被改变的量叫做常量
eg:
int a = 100; // a是变量,而100是常量
float f = 3.14; // f是变量,而3.14是常量
char s[] = "abcd"; // s是变量,"abcd"是常量
1.1 常量拓展
注:初学者跳过拓展部分,至 2.变量
1.1.1 const修饰的常变量
const修饰的常变量不能被重复定义
#include<stdio.h>
int main()
{
const int a = 10;
a = 20;
printf("a的值为:%d",a);
return 0;
}
运行结果:
assignment of read-only variable ‘a’
译:变量a是只读的
const修饰的常变量可以修改吗?
下面定义一个指针,指向a变量所代表的内存,然后修改这个指针
#include<stdio.h>
int main()
{
const int a = 10;
int *b = (int *) &a;
*b = 20;
printf("a的值为:%d\n",a);
return 0;
}
运行结果:
通过上面两个程序,可以说明,在C语言中,const修饰后的常变量只不过是修饰该变量名,它并不能使内存变为只读。也就是说,我们不能通过变量名再去操作这块内存。但是可以通过其它方法,如指针,通过指针是可以修改被const修饰的那块内存的。
const修饰后的常变量,本质上是一个变量
1.1.2 #define 定义的标识符常量
#include <stdio.h>
//#define定义标识符常量
#define NUM 100
int main()
{
printf("%d\n",NUM);
int n = NUM;
printf("%d\n",n);
int arr[NUM] = {0};
return 0;
}
运行结果:
NUM此时是一个常量,值为100
可以理解为NUM是10的符号,NUM就是10,10就是NUM
1.1.3 枚举常量
#include <stdio.h>
enum color
{
red,
green,
yellow
};
int main()
{
printf("%d\n",red);
printf("%d\n",green);
printf("%d\n",yellow);
return 0;
}
运行结果:
也可以为其赋初值
#include <stdio.h>
enum color
{
red = 3,
green,
yellow
};
int main()
{
printf("%d\n",red);
printf("%d\n",green);
printf("%d\n",yellow);
return 0;
}
运行结果:
枚举数据最重要的作用,是使用有意义的单词,来替代无意义的数字,提高程序的可读性
2. 变量
- 在程序运行过程中其值可以改变的量。
- 本质:变量代表内存中具有特定属性的存储单元,变量名实际是符号化的内存地址
- 在C语言中,要求对所用到的变量使用前必须先强制定义,即:先定义,后使用。
2.1 变量拓展
注:初学者跳过拓展部分,至 二、基本数据类型
2.1.1 局部变量
局部变量,也称内部变量,是指在一个函数内部或复合语句内部定义的变量。
也可以浅显的理解为{ }内定义的变量只能在{ }内的范围使用。
#include<stdio.h>
int main()
{
int a = 1;
if (a = 1)
{
int j = 1;
}
printf("%d", j);
return 0;
}
运行结果:
‘j’ undeclared (first use in this function)
译:“ j”未声明(此函数首次使用)
each undeclared identifier is reported only once for each function it appears in
译:每个未声明的标识符对于出现在其中的每个函数只报告一次
就是说 j 是一个局部变量,在 if{} 中有意义,在外边不认识它
将printf() 放在里边就可以,程序如下
#include<stdio.h>
int main()
{
int a = 1;
if (a = 1)
{
int j = 1;
printf("%d\n", j);
}
return 0;
}
运行结果:
2.1.2 全局变量
全局变量也称为外部变量,它是在函数外部定义的变量。
它不属于哪一个函数,它属于一个源程序文件。
#include<stdio.h>
int j = 1;//全局变量
int main()
{
int a = 1;
if (a = 1)
{
printf("%d\n", j);
}
printf("%d\n", j);
return 0;
}
运行结果:
在同一.c文件中,全局变量在任何位置都可以用
二、基本数据类型
1. 整型
在C语言中,整型数据一般用short、int、long三种数据类型来声明
int a = 123;// 定义了一个专门用来存储整数的变量a
int 的本意是 integer,即整数的意思
int a 代表在内存中开辟一块小区域,称为 a,用来存放整数,a 一般被称为变量。
变量 a 所占内存大小,在不同的系统中是不一样的,64位系统典型的大小是4个字节
整型修饰符
short:用来缩短整型变量的尺寸,减少取值范围并节省内存,称为短整型
long:用来增长整型变量的尺寸,增大取值范围并占用更多内存,称为长整型
long long:用来增长整型变量的尺寸,增大取值范围并占用更多内存,称为长长整型
unsigned:用来去除整型变量的符号位,使得整型变量只能表达非负整数
使用整型修饰符后,关键字 int 可以被省略
short a; // 短整型 %hd half
long b; // 长整型 %ld
long long c; // 长长整型 %lld
unsigned e; // 无符号整型 %u
unsigned short f; // 无符号短整型 %hu
unsigned long g; // 无符号长整型 %lu
unsigned long long h; // 无符号长长整型 %llu
2. 浮点型
用来表达实数的数据类型
单精度浮点型(float),典型尺寸是4字节
双精度浮点型(double),典型尺寸是8字节
长双精度浮点型(long double),典型尺寸是16字节
float f1; // 单精度
double f2; // 双精度
long double f3; // 长双精度
浮点型精度
#include<stdio.h>
int main()
{
double a=3.1415926;
float b=3.1415926;
printf("a:%f\nb:%f\n",a,b);
}
运行结果:
C语言中,输出double类型以及float类型时,默认输出6位小数(不足六位以 0 补齐,超过六位按四舍五入截断)
单精度输出:%.2f ,中间数字是保留几位小数的意思,最好不要超过6
双精度输出:%.8lf,中间数字是保留几位小数的意思,最好不要超过15
3. 字符型
字符类型可以表示单个字符,字符类型是 char,char 是 1 个字节(可以存字母或者数字),多个字符称为字符串
char ch1 = 'a'; // 'a'是字符常量,代表字母a
char ch2 = '\n'; // '\n'是不可见字符常量,代表回车
计算机中存储的都是1和0,因此各种字符都必须被映射为某个数字才能存储到计算机中,这种映射关系形成的表称为 ASCII 码表。
数 值 | 字符 | 数 值 | 字符 | 数 值 | 字符 | |||
十进制 | 十六进制 | 十进制 | 十六进制 | 十进制 | 十六进制 | |||
00 | 0x00 | ‘\0’ | 20 | 0x14 | DC4 | 40 | 0x28 | ( |
01 | 0x01 | SOH | 21 | 0x15 | NAK | 41 | 0x29 | ) |
02 | 0x02 | STX | 22 | 0x16 | SYN | 42 | 0x2A | * |
03 | 0x03 | ETX | 23 | 0x17 | ETB | 43 | 0x2B | + |
04 | 0x04 | EOT | 24 | 0x18 | CAN | 44 | 0x2C | , |
05 | 0x05 | ENQ | 25 | 0x19 | EM | 45 | 0x2D | - |
06 | 0x06 | ACK | 26 | 0x1A | SUB | 46 | 0x2E | . |
07 | 0x07 | '\a' | 27 | 0x1B | ESC | 47 | 0x2F | / |
08 | 0x08 | '\b' | 28 | 0x1C | FS | 48 | 0x30 | 0 |
09 | 0x09 | '\t' | 29 | 0x1D | GS | 49 | 0x31 | 1 |
10 | 0x0A | ‘\n’ | 30 | 0x1E | RS | 50 | 0x32 | 2 |
11 | 0x0B | ‘\v’ | 31 | 0x1F | US | 51 | 0x33 | 3 |
12 | 0x0C | '\f' | 32 | 0x20 | SPACE | 52 | 0x34 | 4 |
13 | 0x0D | '\r' | 33 | 0x21 | ! | 53 | 0x35 | 5 |
14 | 0x0E | SO | 34 | 0x22 | EOT | 54 | 0x36 | 6 |
15 | 0x0F | SI | 35 | 0x23 | # | 55 | 0x37 | 7 |
16 | 0x10 | DLE | 36 | 0x24 | $ | 56 | 0x38 | 8 |
17 | 0x11 | DC1 | 37 | 0x25 | % | 57 | 0x39 | 9 |
18 | 0x12 | DC2 | 38 | 0x26 | & | 58 | 0x3A | : |
19 | 0x13 | DC3 | 39 | 0x27 | ' | 59 | 0x3B | ; |
数 值 | 字符 | 数 值 | 字符 | 数 值 | 字符 | |||
十进制 | 十六进制 | 十进制 | 十六进制 | 十进制 | 十六进制 | |||
60 | 0x3C | 83 | 0x53 | S | 106 | 0x6A | j | |
61 | 0x3D | = | 84 | 0x54 | T | 107 | 0x6B | k |
62 | 0x3E | > | 85 | 0x55 | U | 108 | 0x6C | l |
63 | 0x3F | ? | 86 | 0x56 | V | 109 | 0x6D | m |
64 | 0x40 | @ | 87 | 0x57 | W | 110 | 0x6E | n |
65 | 0x41 | A | 88 | 0x58 | X | 111 | 0x6F | o |
66 | 0x42 | B | 89 | 0x59 | Y | 112 | 0x70 | p |
67 | 0x43 | C | 90 | 0x5A | Z | 113 | 0x71 | q |
68 | 0x44 | D | 91 | 0x5B | [ | 114 | 0x72 | r |
69 | 0x45 | E | 92 | 0x5C | \ | 115 | 0x73 | s |
70 | 0x46 | F | 93 | 0x5D | ] | 116 | 0x74 | y |
71 | 0x47 | G | 94 | 0x5E | ^ | 117 | 0x75 | u |
72 | 0x48 | H | 95 | 0x5F | _ | 118 | 0x76 | v |
73 | 0x49 | I | 96 | 0x60 | ` | 119 | 0x77 | w |
74 | 0x4A | J | 97 | 0x61 | a | 120 | 0x79 | x |
75 | 0x4B | K | 98 | 0x62 | b | 121 | 0x70 | y |
76 | 0x4C | L | 99 | 0x63 | c | 122 | 0x7A | z |
77 | 0x4D | M | 100 | 0x64 | d | 123 | 0x7B | { |
78 | 0x4E | N | 101 | 0x65 | e | 124 | 0x7C | | |
79 | 0x4F | O | 102 | 0x66 | f | 125 | 0x7D | } |
80 | 0x50 | P | 103 | 0x67 | g | 126 | 0x7E | ~ |
81 | 0x51 | Q | 104 | 0x68 | h | 127 | 0x7F | DEL |
82 | 0x52 | R | 105 | 0x69 | i |
A对应65
a对应97
字符本质上就是一个单字节的整型,支持整型所有的运算。
eg:
#include<stdio.h>
int main()
{
char c1 = 20;
char c2 = c1 + 'a'; // 等价于 char c2 = 20 + 97;
printf("%c\n", c2); // 以字符形式输出117,即 'u'
printf("%d\n", c2); // 以整型形式输出117
}
运行结果:
转义字符
- 一个字符除了可以用它的实体(也就是真正的字符)表示,还可以用编码值表示。这种使用编码值来间接地表示字符的方式称为转义字符(Escape Character)
- 转义字符以 \ 或者 \x 开头,以 \ 开头表示后跟八进制形式的编码值,以 \x 开头表示后跟十六进制形式的编码值。对于转义字符来说,只能使用八进制或者十六进制
#include<stdio.h>
int main()
{
char b = '\141'; //字符a
char d = '\x61'; //字符a
printf("%c %c\n",b,d);
return 0;
}
运行结果:
对于 ASCII 编码,0~31(十进制)范围内的字符为控制字符,它们都是看不见的,不能在显示器上显示,甚至无法从键盘输入,只能用转义字符的形式来表示。不过,直接使用 ASCII 码记忆不方便,也不容易理解,所以,针对常用的控制字符,C语言又定义了简写方式
\n用来换行,让文本从下一行的开头输出,前面的章节中已经多次使用;
\t用来占位,一般相当于四个空格,或者 tab 键的功能。
单引号、双引号、反斜杠是特殊的字符,不能直接表示:
- 单引号是字符类型的开头和结尾,要使用\'表示,也即'\''
- 双引号是字符串的开头和结尾,要使用\"表示,也即"abc\"123"
- 反斜杠是转义字符的开头,要使用\\表示,也即'\\',或者"abc\\123"
4.布尔类型
布尔型数据只有真、假两种取值,非零为真,零为假。
bool a = 1; // 逻辑真,此处1可以取其他任何非零数值
bool b = 0; // 逻辑假
逻辑真除了 1 之外,其他任何非零数值都表示逻辑真,等价于 1
使用布尔型 bool 定义变量时需要包含系统头文件 stdbool.h
布尔型数据常用在逻辑判断、循环控制等场合
eg:(并不适合初学者)
#include <stdio.h>
#include <stdbool.h>
int main()
{
// 在c语言,非0为真,0为假
// bool为布尔类型,一般只有两种状态 true:真 false:假
// 作用是作为标志位,增加代码的可读性
bool flage = true;
bool flage1 = false;
printf("%d\n",flage1);
enum color
{
yellow=10,
gree,
blue,
red
};
printf("%d\n",yellow);
printf("%d\n",red);
return 0;
}
运行结果: