C语言操作符详解(下)

devtools/2024/11/6 23:28:04/
⽬录
1. 单⽬操作符
2. 逗号表达式
3. 下标访问[]、函数调⽤()
4. 结构成员访问操作符
5. 操作符的属性:优先级、结合性
6. 表达式求值

一    单⽬操作符

分类

!、 ++ -- & * + - ~ sizeof ( 类型 )
1.1  "++"和"--”
二者 分为前置++和后置++;前置--和后置--,使用规则是 前置++先+1后使用,后置++先使用后+1,前置--和后置--与前置++和后置++使用规则一样。

1.2 

作用:取反运算符

例如如果flong表示真则!flong表示假。

1.3  +  -

     这里的“+”是正号“-”表示负号。

      ’+‘对于正负值并没有影响;当然如果你想打印一个数字前面要显示正号这时候就可以使用’+‘;

    ’-‘用来改变一个值的正负 ,负数前面加上’-‘会得到正数,正数前面加上’-‘会得到负数。

 

 1.4   sizeof

作用:用于求取各种类型变量的长度

1.5    (类型)

(类型)表示强制类型转换。

注意将3.14强制转换为整型编译器会自动省去小数点后的1数。

   逗号表达式

     语法:逗号表达式,就是⽤逗号隔开的多个表达式。

1 exp1, exp2, exp3, …expN

     过程:逗号表达式,从左向右依次执⾏计算。整个表达式的结果是最后⼀个表达式的结果。

三   下标访问[]、函数调⽤()

1  下标访问[]

常见于数组中

     操作数:⼀个数组名 + ⼀个索引值(下标)
1   int arr[ 10 ]; // 创建数组
2   arr[ 9 ] = 10 ; // 实⽤下标引⽤操作符。
3   [ ] 的两个操作数是 arr 9

 2  函数调⽤()

     接受⼀个或者多个操作数:第⼀个操作数是函数名,剩余的操作数就是传递给函数的参数。

#include <stdio.h>int Add(int x,int y)
{
return x+y;
}int main()
{
//这里的()就是作为函数调用操作符
printf("hello worad");/2个操作数
Add(3,5)//3个操作数
return 0;
}

 四    结构成员访问操作符

1 结构体

   1.1定义

结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:
标量、数组、指针,甚⾄是其他结构体。

 那为什么会有结构体呢?

当我们想描述学⽣,描述⼀本书时, 描述⼀个学⽣需要名字、年龄、学号、⾝⾼、体重等;
而描述⼀本书需要作者、出版社、定价等,这时单⼀的内置类型是不⾏的。C语⾔为了解决这个问题,增加了结构体这种⾃定义的数据类型,让程序员可以⾃⼰创造适合的类型。

1.2   结构的声明

struct tag
{
  member- list ;
}variable- list ;

 例如描述⼀个学⽣:

struct Stu
{
     char name[ 20 ]; // 名字
     int age; // 年龄
     char sex[ 5 ]; // 性别
    char id[ 20 ]; // 学号
}; // 分号不能丢

 1.3   结构体变量的定义和初始化

变量的定义

struct Point
{
   int x;
    int y;
}p1; // 声明类型的同时定义变量 p1 (p1是全局变量)
struct Point p2 ; //定义结构体变量p2(p1是全局变量)

  变量的初始化

(1) 初始化和指定顺序初始化

struct Point p3 = { 10 , 20 };
struct Stu // 类型声明
{
  char name[ 15 ]; // 名字
     int age; // 年龄
};
struct Stu s1 = { "zhangsan" , 20 } ;//初始化 (要与 struct Stu中局部变量的顺序一一对应)
struct Stu s2 = {.age= 20 , .name= "lisi" }; //指定顺序初始化(可以无顺序)

(2)结构体嵌套初始化

struct Node
{
   int data;
   struct Point p ;
     struct Node * next ;
}n1 = { 10 , { 4 , 5 }, NULL }; //结构体嵌套初始化
struct Node n2 = { 20 , { 5 , 6 }, NULL }; / /结构体嵌套初始化

 1.4     结构成员访问操作符

(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);
        return 0 ;
}

(2) 结构体成员的间接访问

     有时候我们得到的不是⼀个结构体变量,⽽是得到了⼀个指向结构体的指针。使⽤⽅式:结构体指针->成员名。

例如

# include <stdio.h>
struct Point
{
     int x;
     int y;
};
int main ()
{
       struct Point p = { 3 , 4 };
       struct Point * ptr = &p;
       ptr->x = 10 ;
       ptr->y = 20 ;
       printf ( "x = %d y = %d\n" , ptr->x, ptr->y);
return 0 ;
}

   操作符的属性:优先级、结合性

      作用2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。

1   优先级

      定义优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是 不⼀样的

例如

3 + 4 * 5 ;
       上⾯⽰例中,表达式 3 + 4 * 5 ⾥⾯既有加法运算符( + ),⼜有乘法运算符( * )。由于乘法 的优先级⾼于加法,所以会先计算 4 * 5 ,⽽不是先计算 3 + 4。

2    结合性

      定义如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执⾏顺序。⼤部分运算符是左结合(从左到右执⾏),少数运算符是右 结合(从右到左执⾏),⽐如赋值运算符(=)。

例如

5 * 6 / 2 ;
    上⾯⽰例中, * / 的优先级相同,它们都是左结合运算符,所以从左到右执⾏,先计算 5 * 6 再计算 / 2
      重要运算符的优先级顺序 (按照优先级从⾼到低排列),建议⼤概 记住这些操作符的优先级就⾏,其他操作符在使⽤的时候查看下⾯表格就可以了。
圆括号( ()
⾃增运算符( ++ ),⾃减运算符( --
单⽬运算符( + -
乘法( * ),除法( /
加法( + ),减法( -
关系运算符( < > 等)
赋值运算符( =
由于圆括号的优先级最⾼,可以使⽤它改变其他运算符的优先级

 参考:https://zh.cppreference.com/w/c/language/operator_precedence

 那有了操作符的属性:优先级、结合性,就能完全解决问题吗 ?答案是不能:

例如

a*b + c*d + e*f

      表达式1在计算的时候,由于 * + 的优先级⾼,只能保证, * 的计算是⽐ + 早,但是优先级并不 能决定第三个 * ⽐第⼀个 + 早执⾏。

c + --c;

      操作符的优先级只能决定⾃减 -- 的运算在 + 的运算的前⾯,但是我们并没有办法得知, +
作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的

   六    表达式求值

1   整型提升

       定义:   C语⾔中整型算术运算总是⾄少以缺省(默认)整型类型的精度来进⾏的。为了获得这个精度,表达式中的字符和短整型操作数在使⽤之前被转换为普通整型,这种转换称为整 型提升。

2   整型提升的意义:

        表达式的整型运算要在CPU的相应运算器件内执⾏,CPU内整型运算器(ALU)的操作数的字节⻓度⼀般就是int的字节⻓度,同时也是CPU的通⽤寄存器的⻓度。
      因此,即使两个char类型的相加,在CPU执⾏时实际上也要先转换为CPU内整型操作数的标准⻓ 度。
      通⽤CPU(general-purpose CPU)是难以直接实现两个8⽐特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种⻓度可能⼩于int⻓度的整型值,都必须先转换为 int或unsigned int,然后才能送⼊CPU去执⾏运算。

如何进⾏整体提升呢?

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    算术转换

       定义:如果某个操作符的各个操作数属于不同的类型,那么除⾮其中⼀个操作数的转换为另⼀个操作数的类型,否则操作就⽆法进⾏。

下⾯的层次体系称为寻常算术转换。

1     long double
2    double
3    float
4    unsigned long int
5    long int
6    unsigned int
7    int

      如果某个操作数的类型在上⾯这个列表中排名靠后,那么⾸先要转换为另外⼀个操作数的类型后执⾏运算。

本篇文章就到此结束,希望有所能帮到 读者更好的了解操作符操作符操作符。


http://www.ppmy.cn/devtools/131863.html

相关文章

每日一练 | DHCP Relay(DHCP 中继)

01 真题题目 DHCP Relay 又称为 DHCP 中继&#xff0c;下列关于 DHCP Relay 的说法正确的是&#xff08;多选&#xff09;&#xff1a; A. DHCP 协议多采用广播报文&#xff0c;如果出现多个子网则无法穿越&#xff0c;所以需要 DHCP Relay 设备。 B. DHCP Relay 一定是一台交…

什么是区块链中的不可能三角?

定义 区块链中的 “不可能三角”&#xff08;Blockchain Trilemma&#xff09;是指在区块链系统的设计中&#xff0c;很难同时实现去中心化&#xff08;Decentralization&#xff09;、安全性&#xff08;Security&#xff09;和可扩展性&#xff08;Scalability&#xff09;这…

【笔记】拉取镜像

服务器拉取docker镜像 一般会因为网络不行拉不下来 如果没有root的权限的话无法通过改配置文件来修改docker镜像 所以用这种把镜像作为前缀的临时方法&#xff1a; 要注意的是不要加https:// 如下图所示&#xff1a;第一次尝试是错误的&#xff0c;第二次才是正确的

Caffeine 手动策略缓存 put() 方法源码解析

BoundedLocalManualCache put() 方法源码解析 先看一下BoundedLocalManualCache的类图 com.github.benmanes.caffeine.cache.BoundedLocalCache中定义的BoundedLocalManualCache静态内部类。 static class BoundedLocalManualCache<K, V> implements LocalManualCache&…

WPF+MVVM案例实战(二十)- 制作一个雷达辐射效果的按钮

文章目录 1、案例效果2、文件创建与代码实现1、创建文件2、图标资源文件3、源代码获取1、案例效果 2、文件创建与代码实现 1、创建文件 打开 Wpf_Examples 项目,在 Views 文件夹下创建窗体界面 RadarEffactWindow.xaml 。代码功能分两个部分完成,一个是样式,一个是动画。页…

C语言:初识入门篇

专栏说明&#xff1a;本专栏用于C语言学习&#xff0c;文章中出现的代码由C语言实现&#xff0c;如对你学习有所帮助&#xff0c;可以点赞收藏关注&#xff0c;感谢三连。 博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;C语言专栏关注博主&#xff0c;后期持续更新…

利用pythonstudio写的PDF、图片批量水印生成器,可同时为不同读者生成多组水印

现在很多场合需要将PDF或图片加水印&#xff0c;本程序利用pythonstudio编写。 第一步 界面 其中&#xff1a; LstMask:列表框 PopupMenu:PmnMark LstFiles:列表框 PopupMenu:PmnFiles OdFiles:文件选择器 Filter:PDF文件(.PDF)|.PDF|图像文件(.JPG)|.JPG|图像文件(.png…

uniapp使用echart

一 直线图 三中国地图 <template><view class"content"><l-echart ref"chartRef"></l-echart></view> </template><script setup> import { ref, onMounted } from "vue"; import geoJson from &quo…