C语言---Day3
8、常量的定义方式 & 使用方法 & 如何在内存中存储
---常量是固定值,在程序执行期间不会改变;常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量
---常量就是常规的变量,但常量的值在定义后不能进行修改; 可以直接在代码中使用,也可以通过定义常量来使用。
---整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。(后缀不能重复)后缀可以是大写,也可以是小写,U 和 L 的顺序任意。 整数常量可以带有一个后缀表示数据类型---L、U
---浮点常量由整数部分、小数点、小数部分和指数部分组成。可以使用小数形式或者指数形式来表示浮点常量。当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。 浮点数常量可以带有一个后缀表示数据类型--f
---字符常量是括在单引号中,字符常量可以是一个普通的字符(例如 'x')、一个转义序列(例如 '\t'),或一个通用的字符(例如 '\u02C0')。 字符常量的 ASCII 值可以通过强制类型转换转换为整数值
---字符串字面值或常量是括在双引号 " " 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。可以使用空格做分隔符,把一个很长的字符串常量进行分行。 字符串常量在内存中以 null 终止符 \0 结尾
---定义常量:(把常量定义为大写字母形式)
- 使用 #define 预处理器: #define 可以在程序中定义一个常量,它在编译时会被替换为其对应的值。 -----#define 常量名 常量值
- 使用 const 关键字:const 关键字用于声明一个只读变量,即该变量的值不能在程序运行时修改。 -----const 数据类型 常量名 = 常量值;
-区别:
-
替换机制:
#define
是进行简单的文本替换,而const
是声明一个具有类型的常量。#define
定义的常量在编译时会被直接替换为其对应的值,而const
定义的常量在程序运行时会分配内存,并且具有类型信息。 -
类型检查:
#define
不进行类型检查,因为它只是进行简单的文本替换。而const
定义的常量具有类型信息,编译器可以对其进行类型检查。这可以帮助捕获一些潜在的类型错误。 -
作用域:
#define
定义的常量没有作用域限制,它在定义之后的整个代码中都有效。而const
定义的常量具有块级作用域,只在其定义所在的作用域内有效。 -
调试和符号表:使用
#define
定义的常量在符号表中不会有相应的条目,因为它只是进行文本替换。而使用const
定义的常量会在符号表中有相应的条目,有助于调试和可读性。
9、auto 关键字
---auto存储类是所有局部变量默认的存储类,c语言中,关键字auto用于声明一个变量为自动变量,自动变量也称局部变量; 所有局部变量默认都是auto,一般省略不写,它们在函数开始时被创建,在函数结束时被销毁; 在函数内定义变量时,如果没有被声明为其他类型的变量都是自动变量(其他类型指:静态类型变量(static )、寄存器类型变量(register)和外部类型变量(extern))
---c语言中,auto 只能修饰局部变量,只使用auto修饰变量,变量的类型默认为整型int; c++中,关键字auto是一个类型说明符; C语言中使用auto定义的变量可以不予初始化,但在C++中必须初始化
10、运算符
---算术运算符:+、-、*、/、%(取模运算符,整除后的余数)、++(自增运算符,整数值增加 1)、--(自减运算符,整数值减少 1)
---a++ 、a-- 先赋值后运算; ++a、--a 先运算后赋值
// a++ 和 ++a 的区别 int c1; int a1 = 10; c1 = a1++; printf("先赋值后运算:\n"); printf("Line 1 - c1 的值是 %d\n", c1); // c1 = 10 printf("Line 2 - a1 的值是 %d\n", a1); // a1 = 11 a1 = 10; c1 = a1--; printf("Line 3 - c1 的值是 %d\n", c1); // c1 = 10 printf("Line 4 - a1 的值是 %d\n", a1); // a1 = 9 printf("先运算后赋值:\n"); a1 = 10; c1 = ++a1; printf("Line 5 - c1 的值是 %d\n", c1); // 11 printf("Line 6 - a1 的值是 %d\n", a1); // 11 a1 = 10; c1 = --a1; printf("Line 7 - c1 的值是 %d\n", c1); // 9 printf("Line 8 - a1 的值是 %d\n", a1); // 9
---关系运算符:==、 !=、 >、 <、 >=、 <=
---逻辑运算符:&&(逻辑与)、 ||(逻辑或)、 !(逻辑非)
---位运算符:位运算符作用于位,并逐位执行操作; &(按二进制位进行"与"运算)、 | (按二进制位进行"或"运算)、^(按二进制位进行"异或"运算,相同为0,不同为1)、~(按二进制位进行"取反"运算)、
<<(二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0))
>>(二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补 0,负数左补 1,右边丢弃))
// 位运算符 unsigned int a2 = 60; /* 60 = 0011 1100 */ unsigned int b2 = 13; /* 13 = 0000 1101 */ int c2 = 0; c2 = a2 & b2; /* 12 = 0000 1100 */ printf("Line 1 - c2 的值是 %d\n", c2); c2 = a2 | b2; /* 61 = 0011 1101 */ printf("Line 2 - c2 的值是 %d\n", c2); c2 = a2 ^ b2; /* 49 = 0011 0001 */ printf("Line 3 - c2 的值是 %d\n", c2); c2 = ~a2; /* -61 = 1100 0011 */ printf("Line 4 - c2 的值是 %d\n", c2); c2 = a2 << 2; /* 240 = 1111 0000 */ printf("Line 5 - c2 的值是 %d\n", c2); c2 = a2 >> 2; /* 15 = 0000 1111 */ printf("Line 6 - c2 的值是 %d\n", c2);
// a 转为 A 小写转为大写 char toUpper(char a) { return a & ~32; } int main() { printf("B的值为:%c\n", toUpper('B')); printf("b的值为:%c\n", toUpper('b')); return 0; } // A 转为 a 大写转为小写 char toLower(char a) { return a | 32; } int main() { printf("a的值为:%c\n", toLower('a')); printf("A的值为:%c\n", toLower('A')); return 0; }
---赋值运算符: =、 +=、 -=、 *=、 /=、 %=(C %= A 相当于 C = C % A)、 <<=(左移且赋值)、>>=(右移且赋值)、&=(按位与且赋值)^=(按位异或且赋值)、|=(按位或且赋值)
// 赋值运算符 int a = 21; int c; c = a; printf("Line 1 - = 运算符实例,c 的值 = %d\n", c); // 21 c += a; printf("Line 2 - += 运算符实例,c 的值 = %d\n", c); // 42 c -= a; printf("Line 3 - -= 运算符实例,c 的值 = %d\n", c); // 21 c *= a; printf("Line 4 - *= 运算符实例,c 的值 = %d\n", c); // 441 c /= a; printf("Line 5 - /= 运算符实例,c 的值 = %d\n", c); // 21 c = 200; c %= a; printf("Line 6 - %%= 运算符实例,c 的值 = %d\n", c); // 11 c <<= 2; printf("Line 7 - <<= 运算符实例,c 的值 = %d\n", c); // 44 c >>= 2; printf("Line 8 - >>= 运算符实例,c 的值 = %d\n", c); // 11 c &= 2; printf("Line 9 - &= 运算符实例,c 的值 = %d\n", c); // 2 c ^= 2; printf("Line 10 - ^= 运算符实例,c 的值 = %d\n", c); // 0 c |= 2; printf("Line 11 - |= 运算符实例,c 的值 = %d\n", c); // 2
---杂项运算符: sizeof() 返回变量的大小、 & 返回变量的地址、 * 指向一个变量、 ?: 条件表达式
// 杂项运算符 int x = 4; short y; double z; int* ptr; /* sizeof 运算符实例 */ printf("Line 1 - 变量 x 的大小 = %lu\n", sizeof(x)); // 4 printf("Line 2 - 变量 y 的大小 = %lu\n", sizeof(y)); // 2 printf("Line 3 - 变量 z 的大小 = %lu\n", sizeof(z)); // 8 /* & 和 * 运算符实例 */ ptr = &x; /* 'ptr' 现在包含 'x' 的地址 */ printf("x 的值是 %d\n", x); // 4 printf("*ptr 是 %d\n", *ptr); // 4 /* 三元运算符实例 */ x = 10; y = (x == 1) ? 20 : 30; printf("y 的值是 %d\n", y); // 30 y = (x == 10) ? 20 : 30; printf("y 的值是 %d\n", y); // 20
---运算符优先级:后缀(() [] -> . ++ - - )、一元(+ - ! ~ ++ - - (type)* & sizeof)、乘除(* / %)、加减(+ -)、关系(< <= > >=)、相等(== !=)、位与 AND(&)、位异或 XOR(^)、位或 OR(|)、逻辑与 AND(&&)、逻辑或 OR(||)、条件(?: )、赋值(= += -= *= /= %=>>= <<= &= ^= |=)、逗号
// 运算符优先级 int j = 20; int k = 10; int l = 15; int m = 5; int n; n = (j + k) * l / m; // ( 30 * 15 ) / 5 printf("(j + k) * l / m 的值是 %d\n", n); // 90 n = ((j + k) * l) / m; // (30 * 15 ) / 5 printf("((j + k) * l) / m 的值是 %d\n", n); // 90 n = (j + k) * (l / m); // (30) * (15/5) printf("(j + k) * (l / m) 的值是 %d\n", n); // 90 n = j + (k * l) / m; // 20 + (150/5) printf("j + (k * l) / m 的值是 %d\n", n); // 50