
✨个人主页: 熬夜学编程的小林
💗系列专栏: 【C语言详解】 【数据结构详解】
操作符
1、下标访问[]、函数调用()
1.1、[ ] 下标引用操作符
1.2、函数调用操作符
2、结构成员访问操作符
2.1、结构体
2.1.1、结构的声明
2.1.2、结构体变量的定义和初始化
2.2、结构成员访问操作符
2.2.1、结构体成员的直接访问
2.2.2、结构体成员的间接访问
3、操作符的属性:优先级、结合性
3.1、优先级
3.2、结合性
4、表达式求值
4.1、整型提升
4.2、算术转换
4.3、问题表达式解析
4.3.1、表达式1
4.3.2、表达式2
4.3.3、表达式3
4.3.4、表达式4
4.3.5、表达式5:
4.4、总结
1、下标访问[]、函数调用()
1.1、[ ] 下标引用操作符
int arr[10];//创建数组
arr[9] = 10;//实⽤下标引⽤操作符。
[ ]的两个操作数是arr和9。 1.2、函数调用操作符
接受⼀个或者多个操作数:第⼀个操作数是 函数名 ,剩余的操作数就是传递给函数的 参数 。
#include <stdio.h>
void test1()
{printf("hehe\n");
}
void test2(const char *str)
{printf("%s\n", str);
}
int main()
{test1(); //这⾥的()就是作为函数调⽤操作符。test2("hello world");//这⾥的()就是函数调⽤操作符。test2为函数名,"hello world"为参数return 0;
} 2、结构成员访问操作符
2.1、结构体
结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:标量、数组、指针,甚至是其他结构体。
2.1.1、结构的声明
struct tag
{member-list;//成员列表
}variable-list;//全局结构体变量 struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}; //分号不能丢 2.1.2、结构体变量的定义和初始化
//代码1:变量的定义
struct Point
{int x;int y;
}p1; //声明类型的同时定义全局变量p1
struct Point p2; //定义结构体变量p2 在main函数内则是局部变量,main函数外则是全局变量
//代码2:初始化。
struct Point p3 = {10, 20};
struct Stu //类型声明
{char name[15];//名字int age; //年龄
};
struct Stu s1 = {"zhangsan", 20};//初始化
struct Stu s2 = {.age=20, .name="lisi"};//指定顺序初始化
//代码3
struct Node
{int data;struct Point p;struct Node* next;
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化 2.2、结构成员访问操作符
2.2.1、结构体成员的直接访问
结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。
#include <stdio.h>
struct Point
{int x;int y;
}p = {1,2};//创建全局变量以及初始化
int main()
{printf("x: %d y: %d\n", p.x, p.y);//打印结构体中x y的值return 0;
} 2.2.2、结构体成员的间接访问
#include <stdio.h>
struct Point
{int x;int y;
};
int main()
{struct Point p = {3, 4};//创建局部变量以及初始化struct Point *ptr = &p;//ptr位结构体类型指针变量 *代表指针符号 ptr指向p的地址 &为取地址符号ptr->x = 10;ptr->y = 20;printf("x = %d y = %d\n", ptr->x, ptr->y);return 0;
} #include <stdio.h>
#include <string.h>
struct Stu
{char name[15];//名字int age; //年龄
};
void print_stu(struct Stu s)
{printf("%s %d\n", s.name, s.age);
}
void set_stu(struct Stu* ps)
{strcpy(ps->name, "李四");ps->age = 28;
}
int main()
{struct Stu s = { "张三", 20 };print_stu(s);//打印结构体set_stu(&s);//修改结构体值 print_stu(s);//打印结构体return 0;
} 注:修改值需要传地址,因为形参是实参的一份临时拷贝,改变形参不会影响实参。在后序指针还会详细讲解。
3、操作符的属性:优先级、结合性
3.1、优先级
优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执行。各种运算符的优先级是不⼀样的。
3 + 4 * 5; 3.2、结合性
5 * 6 / 2;
4、表达式求值
4.1、整型提升
表达式的整型运算要在CPU的相应运算器件内执⾏,CPU内整型运算器(ALU)的操作数的字节长度⼀般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。 通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
//实例1
char a,b,c;
...
a = b + c; 1. 有符号整数提升是按照变量的数据类型的符号位来提升的2. 无符号整数提升,⾼位补0
//负数的整形提升
char c1 = -1;
变量c1的⼆进制位(补码)中只有8个⽐特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的⼆进制位(补码)中只有8个⽐特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//⽆符号整形提升,⾼位补0 4.2、算术转换
long double
double
float
unsigned long int
long int
unsigned int
int 4.3、问题表达式解析
4.3.1、表达式1
//表达式的求值部分由操作符的优先级决定。
//表达式1
a*b + c*d + e*f a*b
c*d
a*b + c*d
e*f
a*b + c*d + e*f 或者
a*b
c*d
e*f
a*b + c*d
a*b + c*d + e*f 4.3.2、表达式2
//表达式2
c + --c; 4.3.3、表达式3
//表达式3
int main()
{int i = 10;i = i-- - --i * ( i = -3 ) * i++ + ++i;printf("i = %d\n", i);return 0;
} 4.3.4、表达式4
#include <sdtio.h>
int fun()
{static int count = 1;return ++count;
}
int main()
{int answer;answer = fun() - fun() * fun();printf( "%d\n", answer);//输出多少?return 0;
}
4.3.5、表达式5:
//表达式5
#include <stdio.h>
int main()
{int i = 1;int ret = (++i) + (++i) + (++i);printf("%d\n", ret);printf("%d\n", i);return 0;
}
//尝试在linux 环境gcc编译器,VS2022环境下都执⾏,看结果。 
VS2022运行结果:
