1.基本运算符
1.1赋值运算符:=
在C语言中,=不是等于的意思,而是一个赋值运算符。
用于将右边的值赋给左边的变量。
左边必须是一个可存储值的变量,右边可以是常量、表达式、函数的返回值等。
如:
int a = 10; // 将10赋值给变量 a
这里,=
是一个赋值操作符,表示把右边的值 10
存储到左边的变量 a
中
下面介绍几个概念:
数据对象:用于存储值的数据存储区统称为数据对象
左值:表示的是内存中某个可以被赋值的对象的地址。换句话说,左值是一个能够持久存在的内存位置,通常它是一个变量或数组元素,能够通过赋值语句改变它的值。
可修改左值:指那些可以被修改(赋值)的左值。C语言中的左值不一定都可以修改。
int x = 10; // x 是一个可修改左值
x = 20; // 通过赋值操作修改了 x 的值int arr[3] = {1, 2, 3};
arr[0] = 5; // arr[0] 是可修改左值,修改了它的值struct Person {
int age;
};
struct Person p = {25};
p.age = 30; // p.age 是可修改左值,修改了它的值
const int x = 10;
x = 20; // 错误:x 是常量,不能修改5 = x; // 错误:5 是右值,不能被修改
右值:指的是能够赋值给可修改左值的量,且本身不是左值
1.2加法运算符:+
算数加法
+
运算符用于两个操作数的加法运算。它可以用于整数、浮点数、字符等类型的数据。
int a = 5, b = 3;
int sum = a + b; // sum = 5 + 3,结果是 8
字符串连接
对于字符串类型,+
运算符并不能直接连接两个字符串,但是在C++中它是支持字符串连接的。C语言中通常使用 strcat()
函数进行字符串拼接。
char str1[20] = "Hello ";
char str2[] = "World!";
strcat(str1, str2); // 使用 strcat 来拼接两个字符串
1.3减法运算符:-
算数减法
-
运算符用于两个操作数的减法运算,也可以用于整数、浮点数、字符等类型的数据。
int a = 5, b = 3;
int difference = a - b; // difference = 5 - 3,结果是 2
负号(取反)
-
运算符也可以作为一元运算符,表示取负数(即改变数字的符号)。
int a = 5;
int b = -a; // b = -5
1.4乘法运算符:*
*
运算符用于执行两个数的乘法运算。它可以用于整数、浮点数、字符等类型的数据,结果的类型通常与操作数类型兼容。
int a = 5, b = 3;
int result = a * b; // result = 5 * 3,结果是 15float x = 2.5, y = 4.0;
float result = x * y; // result = 2.5 * 4.0,结果是 10.0
1.5除法运算符:/
/
运算符用于两个数的除法运算。它可以用于整数、浮点数等类型的数据.
如果两个操作数都是整数类型(如 int
),则执行整数除法,会丢弃余数。如果出现除数为零的情况,会导致运行时错误(如除以零错误)。
int a = 10, b = 3;
int result = a / b; // result = 10 / 3,结果是 3,余数不要
如果操作数是浮点数(如 float
或 double
),则执行浮点除法,结果会是一个浮点数,保留小数部分。
float x = 10.0, y = 3.0;
float result = x / y; // result = 10.0 / 3.0,结果是 3.333333
当一个整数与浮点数相除时,结果会自动转换为浮点数,因为浮点数类型的结果能更好地表示精度。
int a = 10;
float b = 3.0;
float result = a / b; // result = 10 / 3.0,结果是 3.333333
1.6取余运算符:%
%
运算符用于计算两个整数相除后的余数。它的操作数通常是整数类型(int
、long
等)。
当使用 %
运算符时,它会返回除法运算的余数,而不考虑商。
int a = 10, b = 3;
int result = a % b; // result = 10 % 3,结果是 1,因为 10 除以 3 商是 3,余数是 1
符号规则:取余运算符的结果的符号与被除数(左操作数)的符号一致。
例如,10 % 3
的结果是 1
,而 -10 % 3
的结果是 -1
,因为余数的符号与被除数相同
2.其他运算符
2.1sizeof运算符和size_t类型
在前面的笔记中见过了sizeof运算符,sizeof运算符以字节为单位返回运算对象的大小,运算对象可以是具体的数据对象(如:变量名)或类型,如果运算对象是类型的话(如:float),则必须使用圆括号将其括起来。
C语言规定,sizeof返回size_t类型的值,这是一个无符号整型类型的,在C99标准中,新增了%zd转换说明用于printf()显示size_t类型的值,如果系统不支持%zd,可以使用%u或%lu来代替。
#include <stdio.h>
int main() {
int a = 10;
double b = 3.14;
// 获取 int 类型变量 a 的大小
printf("Size of a (int): %zd bytes\n", sizeof a); // Size of a(int) : 4 bytes
// 获取 double 类型变量 b 的大小
printf("Size of b (double): %zd bytes\n", sizeof(b)); // Size of b(double) : 8 bytes
// 获取 int 类型的大小
// 需要用圆括号将 int 括起来
printf("Size of int: %zu bytes\n", sizeof(int)); // Size of int: 4 bytes
return 0;
}
2.2递增运算符:++
递增运算符的基本作用是:增加1
递增运算符有两种形式:
-
前缀递增(
++a
):先将变量的值增加 1,然后再返回增加后的值。 -
后缀递增(
a++
):先返回变量当前的值,再将变量的值增加 1。
#include <stdio.h>
int main() {
int a = 5;
// 前缀递增:先将a增加1,再返回新的值
printf("++a = %d\n", ++a); // a 先变成 6,返回 6
printf("a after ++a = %d\n", a); // a = 6
// 后缀递增:先返回当前的 a 值,再将 a 增加 1
printf("a++ = %d\n", a++); // 先返回 6,再把 a 增加到 7
printf("a after a++ = %d\n", a); // a = 7
return 0;
}
2.3递减运算符:--
递减运算符的基本作用是:减少1
递减运算符同样有两种形式:
-
前缀递减(
--a
):先将变量的值减少 1,然后再返回减少后的值。 -
后缀递减(
a--
):先返回变量当前的值,再将变量的值减少 1。
#include <stdio.h>
int main() {
int a = 5;
// 前缀递减:先将 a 减少 1,再返回新的值
printf("--a = %d\n", --a); // a 先变成 4,返回 4
printf("a after --a = %d\n", a); // a = 4
// 后缀递减:先返回当前的 a 值,再将 a 减少 1
printf("a-- = %d\n", a--); // 先返回 4,再把 a 减少到 3
printf("a after a-- = %d\n", a); // a = 3
return 0;
}
2.4前缀和后缀递增/递减的区别
前缀递增 (++a
) 和前缀递减 (--a
):
-
先修改变量的值(增加或减少),然后返回修改后的值。
-
适用于需要立即获取修改后值的场景。
后缀递增 (a++
) 和后缀递减 (a--
):
-
先返回变量当前的值,再修改变量的值(增加或减少)。
-
常用于在表达式中,返回原值而后再改变变量值。
3.表达式和语句
3.1表达式
表达式 是由一个或多个操作数(变量、常量、函数、操作符等)构成的组合,表达式求值的结果是一个值(通常是某种类型的数据)。表达式执行时,可以进行计算、赋值、逻辑判断等操作。
常见的表达式类型:
-
算术表达式:如
a + b
、a - b
、a * b
、a / b
、a % b
-
关系表达式:如
a == b
、a > b
、a < b
等(结果为布尔值true
或false
) -
逻辑表达式:如
a && b
、a || b
、!a
-
赋值表达式:如
a = 10
、b += 5
-
自增/自减表达式:如
a++
、--b
-
条件(三目)表达式:如
a > b ? a : b
-
函数调用表达式:如
printf("Hello, World!")
#include <stdio.h>
int main() {
int a = 5, b = 3;
int result;
// 算术表达式
result = a + b; // a + b 计算结果赋给 result
printf("a + b = %d\n", result); // 输出 8
// 关系表达式
if (a > b) {
printf("a大于b\n");
}
// 逻辑表达式
if (a != b && b < 10) {
printf("逻辑表达式为真(true)\n");
}
// 条件(三目)表达式
result = (a > b) ? a : b; // 如果 a > b 则 result = a,否则 result = b
printf("三目表达式的结果为: %d\n", result);
return 0;
}
3.2语句
语句 是程序的基本执行单元,表示程序的某个动作或操作。语句执行时,它可以包含表达式,也可以是其他类型的控制结构,如条件语句、循环语句、跳转语句等。语句的执行不一定会返回值,而是完成一个动作,如赋值、输出、条件判断等。
在 C 语言中,语句一般以分号 (;
) 结尾,表示语句的结束。
常见的语句类型:
-
表达式语句:是由表达式构成的语句,通常用于执行计算或赋值操作。
a = 5; // 赋值语句 result = a + b; // 算术运算语句
-
声明语句:用于声明变量或常量。
int x = 10; // 变量声明语句
-
条件语句:根据某个条件选择执行不同的代码块,常见的有
if
和switch
。if (a > b) { printf("a是大于b的\n"); } else { printf("b是小于或者等于a的\n"); }
-
循环语句:用于重复执行某个代码块,常见的有
for
、while
和do...while
。for (int i = 0; i < 5; i++) { printf("i = %d\n", i); }
-
跳转语句:控制程序执行的流程,常见的有
break
、continue
和return
。if (a < b) { return 0; // 提前结束函数的执行 }
-
复合语句:由多个语句组成的语句块,通常用
{}
来包含。{ int a = 10; a += 5; printf("%d\n", a); }
4.类型转换
在 C 语言中,类型转换是指将一种数据类型的值转换成另一种数据类型的过程。
类型转换通常分为两种:隐式类型转换(自动类型转换)和 显式类型转换(强制类型转换)。
4.1隐式类型转换
隐式类型转换是由编译器自动完成的转换过程。发生在不同数据类型之间的操作数参与运算时,编译器会根据规则自动将较小范围的类型转换为较大范围的类型,从而避免数据丢失。
规则:
-
整数类型转换:较小的整数类型(如
char
、short
)会被自动转换为int
类型。如果操作数的结果会超出int
的范围,可能会转换为long
或更大的类型。 -
浮点类型转换:
float
类型会自动转换为double
类型。long double
也会自动转换为double
类型。 -
不同整数类型之间的转换:如
short
转换为int
,int
转换为long
。
#include <stdio.h>
int main() {
int a = 5;
double b = 3.14;
// 隐式类型转换:int -> double
double result = a + b; // a 会被自动转换为 double 类型,结果为 double 类型
printf("Result: %.2f\n", result); // 输出 8.14
// 隐式类型转换:short -> int
short s = 100;
int i = s + a; // short 类型 s 会自动转换为 int 类型
printf("i = %d\n", i); // 输出 105
return 0;
}
4.2显式类型转换
显示类型转换是由程序员手动进行的类型转换。
语法:
(type) expression
type 是目标类型,表示你希望转换成的类型。
expression 是要进行转换的表达式。
#include <stdio.h>
int main() {
double a = 5.75;
int b;
// 强制类型转换:double -> int
b = (int) a; // 将 double 类型强制转换为 int 类型
printf("b = %d\n", b); // 输出 5,丢失小数部分
// 强制类型转换:float -> int
float c = 10.56f;
b = (int) c; // 将 float 类型强制转换为 int 类型
printf("b = %d\n", b); // 输出 10,丢失小数部分
return 0;
}