变量
概念:
在程序的运行期间可能会发生改变的值。
定义:
存储类型 数据类型(举例) 变量名(举例)
auto(省略时默认为auto) int a
(auto) int a;
初始化:
① 先定义,后初始化:
(auto) int a; // 定义
a = 6; // 初始化(赋值)
② 定义时初始化:
(auto) int a = 6;
变量名:
遵循标识符的命名规则。
标识符的命名规则:
1)由字母、数字、下划线组成;
2)开头不能是数字;
3)不能和关键字重复;
练习:
x y sum a100 _A7b_3x 3’a x*y @ b.8 while
局部变量 与 全局变量
数据类型
#include <stdio.h>
int main(int argc, char const *argv[])
{
float a1 = 123.4567; // float最高精度7位有效数字
float a2 = 123.456789;
double b1 = 123456789.1234567;
double b2 = 123456789.123456789; // double最高精度16位有效数字
printf("%f\n", a1);
printf("%f\n", a2);
printf("%.12f\n", b1); // 本机仅保留小数点后7位
printf("%.12f\n", b2);
printf("%e\n", b1);
printf("%e\n", b2);
printf("%d\n", sizeof(char));
printf("%d\n", sizeof(short));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(long));
printf("%d\n", sizeof(float));
printf("%d\n", sizeof(double));
printf("%d\n", sizeof(long double));
return 0;
}
运行结果如下:
常量
概念:
程序运行中不会发生变化的量。
分类:
1. 字符型常量
用 ’ ’ 括起来的一个字符。例如’a’ ,代表字符a;而纯字母a代表变量。
数字被定义为字符型之后,就不能再参与数值运算。例如’5’和5是不同的。
#include <stdio.h>
int main(int argc, char const *argv[])
{
char ch = '5';
printf("%c %d\n", ch, ch);
return 0;
}
运行结果如下:
转义字符
#include <stdio.h>
int main(int argc, char const *argv[])
{
char v = 'V';
char dec = 86; //十进制
char oct = '\126'; //八进制
char hex = '\x56'; //十六进制
printf("%c %c %c %c\n", v, dec, oct, hex); //decimal、octal/octonary、hexadecimal
return 0;
}
运行结果如下:
2. 字符串常量
用 " " 括起来的一串字符。双引号只起到定界的作用,且双引号中的符号不能是双引号和反斜杠。
C语言中,字符串常量在内存中存储时,系统自动在字符串的末尾加一个“串结束标志”,即ASCII码值为0的字符NULL,通常用"\0"表示。因此,长度为n个字符的字符串常量,在内存中占有n+1个字节的存储空间。
“Hola” 是 5 个字符,而不是 4个。
#include <stdio.h>
int main(int argc, char const *argv[])
{
char *str1 = "Hello!";
char str2[5] = "Hola!"; // 中括号内可填入>=5的任意数字,也可不填;否则弹出警告
printf("%s\n", str1);
puts(str2);
return 0;
}
运行结果如下:
3. 整型常量
十进制整数的表示最为简单,不需要有任何前缀。
八进制整数需要以“0”作为前缀开头;十六进制的整数需要以“0x”作为前缀开头。
整型常量可在结尾加上“L”或“l”代表长整型,“U”或“u”代表无符号整型。
4. 浮点型常量
float(占 4 个字节) double(占 8 个字节)
C语言中,只有十进制的实数,有一般形式和指数形式两种表示方法,所有浮点常量都被默认为double类型。
5. 指数常量
<尾数> E(e) <整型指数>
指数形式通常用于表示极大或极小的数,更简洁,可读性更好,例:
3e8 来表示 3108
2e-12 来表示 210-12
6. 标识常量
define
宏定义:起标识作用
名字:遵循标识符的命名规则,但一般大写表示。
格式:#define 宏名 常量或表达式/替换列表
特点:只能单纯替换,不会进行运算(原样替换,替换完再计算)
#define N 2
#define M N+3 // M = N+3 = 2+3 != 5
#define NUM N+M/2+1
void main()
{
int a = NUM;
printf("%d\n", a); // 结果为6
}
// N+M/2+1 --> 2+2+3/2+1 // 去尾,得6
#define HELLO hola // 将所有的HELLO替换为hola
#define N 15 // 将所有的N替换为15,常用于数组中
int arr[N];
#include <stdio.h>
#define M 57
#define Max m>n?m:n
#define Min(m, n) m<n?m:n
int main(int argc, char const *argv[])
{
int m, n;
scanf("%d %d", &m, &n); // 若不指定 m、n 的值,则结果随机
printf("%c\n", M);
printf("%d\n", Max);
printf("%d\n", Min(m, n));
return 0;
}
运行结果如下:
const
格式化输出函数 printf
终端输入:man 3 printf,可知 printf 的返回值为整型。
函数原型:
int printf(const char *format, …);
功能:
格式化字符串输出(按照指定格式向终端输出)
参数:
format:指定输出格式,以字符串输出。“… ”代表要输出的若干个变量/表达式。
返回值:
成功返回正确输出字符的个数。
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a = 5, b = 15, c = 155;
char d = 126;
int count1 = printf("%d\n", a);
int count2 = printf("%d\n", b);
int count3 = printf("%d\n", c);
int count4 = printf("%c\n", d);
printf("%d\t%d\t%d\t%d\n", count1, count2, count3, count4);
return 0;
}
运行结果如下:
printf 支持的格式
printf 支持的格式说明符的修饰符
练习:
printf 常用转义字符
终端输入:man printf
格式化输入函数 scanf
终端输入:man scanf
函数原型:
int scanf(const char *format, …);
功能:
按格式从终端输入,存入地址表指定存储单元中,并按回车键结束。
遇到以下情况则认为该数据结束,① 空格、Tab 或 回车;② 宽度结束; ③ 非法输入。
参数:
format:指定输入格式,“… ”代表要输入的若干个变量的地址表。
返回值:
成功返回正确输入变量的个数;当遇到非法输入时,返回值将小于实际变量的个数
scanf 支持的格式
scanf 支持的格式说明符的修饰符
字符输出函数 putchar
终端输入:man putchar
函数原型:
int putchar(int c); // 括号内可以为十进制整数、‘单个字符’、‘\八进制数’、‘\x十六进制数’
功能:
向终端输出一个字符。
参数:
要输出的字符常量的ASCII值。也可为表达式。
返回值:
要输出字符的ASCII值。
字符输入函数 getchar
终端输入:man getchar
函数原型:
int getchar (void);
功能:
从终端输入一个字符。
参数:
无
返回值:
返回读到的字符的ASCII值。
// 用 getchar、putchar 实现大小写字母转换
#include <stdio.h>
int main(int argc, char const *argv[])
{
int ch = getchar();
if(ch >= 65 && ch <= 90)
putchar(ch + 32);
else if(ch >= 97 && ch <= 122)
putchar(ch - 32);
else
putchar(ch);
putchar('\n');
return 0;
}
垃圾字符回收
当使用 scanf 输入数据时,遇到以下情况则认为该数据结束,
① 空格、Tab 或 回车;② 宽度结束; ③ 非法输入。
char ch1, ch2;
scanf("%c%c", &ch1, &ch2); // 输入a、空格、b,
printf("ch1=%c ch2=%c\n", ch1, ch2); // 将输出ch1=a ch2=空格
运行结果如下:
方法1:添加空格
可以回收一个或多个的空格、Tab 和 回车。
char ch1, ch2;
scanf("%c %c", &ch1, &ch2); // 输入a、3个空格、b,
printf("ch1=%c ch2=%c\n", ch1, ch2); // 将输出ch1=a ch2=b
运行结果如下:
方法2:%*c
一个 %*c 只能回收一个字符。
char ch1, ch2;
scanf("%c%*c%c", &ch1, &ch2); // 输入a、2个空格、b,
printf("ch1=%c ch2=%c\n", ch1, ch2); // 将输出ch1=a ch2=空格
运行结果如下:
char ch1, ch2;
scanf("%c%*c%*c%c", &ch1, &ch2); // 输入a、2个空格、b,
printf("ch1=%c ch2=%c\n", ch1, ch2); // 将输出ch1=a ch2=b
运行结果如下:
方法3:getchar();
只能回收一个字符,一般用于循环中。
#include <stdio.h>
int main(int argc, char const *argv[])
{
while (1){
char ch;
scanf("%c", &ch);
printf("%c\n", ch);
while (getchar() != '\n') // 若不加此循环,如下图2所示。加一句getchar();平替也可。
{
/* code */
}
}
return 0;
}
运行结果如下: