首页 > 其他分享 >C语言笔记(第n版):数据类型与运算

C语言笔记(第n版):数据类型与运算

时间:2024-07-03 22:26:43浏览次数:18  
标签:常量 int 数据类型 笔记 C语言 枚举 表达式 变量

        尽管对于计算机而言无所谓数据类型,因为所有的数据都在计算机中以二进制数进行存储,运输和计算,但是对数据进行人为的划定有益于人们对于数据的操作。

        在C语言中对于数据类型的划分(因人而异)大致为:

一、基本数据类型

 什么是数据类型?

        每一种编程语言都有它自己的数据类型体系,在多数教程中,什么是数据类型似乎是比较少讨论(或许是我忘了,不管了),但是只要讨论,就会发现(我就会发现)可以通用。下面引用自一个C++教程网站(https://www.learncpp.com/)的话:

data type tells the compiler how to interpret a piece of data into a meaningful value. 

数据类型告诉编译器如何将一段数据解释为有意义的值。

data type (more commonly just called a type) determines what kind of value (e.g. a number, a letter, text, etc…) the object will store.

数据类型(通常称为类型)决定了对象将存储什么样的值(例如数字、字母、文本等)。

        用我的话说,所谓的数据类型就是一种定义,它规定了在一块连续的内存空间上可以进行的操作(取存改值等)以及一些属性(空间大小等)。

一张copy过来的基本数据类型大小参考表
源自他处

        上表大致显示了C基本数据类型的大概,值得说明的是在C语言中一种数据类型的所占字节,或者说大小是有关于具体平台的,这或多或少被程序员所诟病,这好比我在拿盒子堆积木,我总是希望我所放置的那个盒子就是我看到的那样的大小,而不是说等到一定的时候上面的盒子压下来,才知道是个空包,这多少让人有点焦虑。

        至于为什么数据类型会随平台的不同有所差异呢,这个读者可以自行了解,总的来说算是C平台可移植性的一种代价。同时C中也有一种库可以保证数据类型的大小的固定性,也算是一种弥补吧,这里不多说了。

 二、变量、常量与字面量

        在不少编程语言中,几乎都能找到这三样东西的影子,定义或许有些差异,不过也基本相同(就我了解到的而言)。

(一)变量

从数学到C

        变量这个词在数学中也普遍存在,通常我们称之为x。在实际问题中,诸如小明每天挣3元,问x天后小明可以挣多少钱?

        我们可以很容易列出

y=3x

        这样的数学表达式,但是这是对的吗?请注意这里的x可是天数,嗯,所以我们应该这样

        y=3x ,\: where \: x \: \epsilon \: \mathbb{N}^{+}

        可是这就对了吗?注意,小明可不是长生不老,也有可能小明看累死累活就这么点工资不干了,总之,x不应该是一个无上限的自然数,所以我们又有了以下的数学表达式

y=3x ,\: where \: x \: \epsilon \: \mathbb{N}^{+} and \: x<30

        嗯,看起来对于这个问题,我们已经解决了,但是这跟编程语言,或者跟C中的变量有什么关系吗?有,当然有。让我们试着用C语言描述我们的表达式:

        首先,我们需要一个在C中可以表示\mathbb{N}的东西,显然,想想也没有,毕竟\mathbb{N}可是有下限,无上限,计算机可存储不了无限的数字。不过,回到我们的问题,我们真的需要无上限吗?显然,并不必要,我们只需要一个能包含0~30范围的数集即可。

        嗯,所以我们可以选择上面数据类型中的unsigned \: char,它的取值范围可以。

        接下来,就是我们的变量x,幸运的是,在C中我们也可以直接用x表示x,嗯,听起来怪怪的。

        然后就是yy是因变量,所以也是变量,可以预见y的值域为[0, 90)。

        最后,让我们具体实现,这里我们使用gcc,源码如下(嗯,现在只干3天了),编译一下

        

// hello.c
 
#include <stdio.h>
 
int main()
{   

    y = 3x,  where x ∈ unsigned char and x < 3

    return 0;
}

        然后就会出现一堆问题

       不过,不要慌,要学会看报错提示,首先第一个说'y' undeclared (first use in this function),y没有定义。什么叫没有定义,这就好比,我说110,你可能会想这是报警电话,不过这也可能是一个数字而已,也就是这个数字存在二义性,而在计算机程序中不应该这样,你应该在让计算机去执行代码前就确切地说明,而不是等计算机遇到这个符号,还要从计算机中跳出一个人说,你这家伙写得这是啥?

        那么怎么定义y,如果以数学语言,我们可能会说y是一个值域为[0, 90)的自然数,在C语言中我们应该这么说

        unsigned\: char \: y;

        什么意思呢?这段代码表明,我们定义了一个变量y,它的取值范围为unsigned char的取值范围,更一般地,我们会说,定义了一个unsigned char类型的变量y

        这里有两点值得注意的是,我们没有限定y取值范围为[0,90),在C中也不提供这样的机制,(不过请看后面的特例),在原数学问题中,我们也只需要说y是一个自然数即可。我们也不需要这样,因为y不过是一个数值容器,无论x是<3也好<30也好,我们只需要y能够正确存储结果,从这个角度而言,unsigned\: short \: y;也可以。第二点是这里加了分号,这后面会讨论。

源码再次修改

// hello.c
 
#include <stdio.h>
 
int main()
{   
    unsigned char y;
    y = 3x,  where x ∈ unsigned char and x < 3

    return 0;
}

编译后那个错误就会消失,不过还是有其它错误:

错误提示在一个整数3后面的非法x后缀,什么意思呢?invalid就是不允许这样操作,我们想要表示的并不能有效翻译成代码语言,在数学中3x,表示3 \times x,可在C中没有这样的转换,这是数学表达式转换成C语言非常需要注意的地方,我们要这样写3\ast x

// hello.c
 
#include <stdio.h>
 
int main()
{   
    unsigned char y;
    y = 3*x,  where x ∈ unsigned char and x < 3

    return 0;
}

编译后,发现x未定义,不过x不是在后面说明了吗,移到前面?不对,第二个错误显示C编译器不认识where,所以数学表达式转成C语言并不能拿来主义,对于一个变量的声明定义,有且有一条正途,即类似y一样

让我们再次修改,可以看到一下子干净了,不过提示我们少了东西,这个后面说,现在就加上就好。

bingo!我们成功将一个数学表达式用C语言表述,不过,嗯,少了输出。

我们改改

// hello.c
 
#include <stdio.h>
 
int main()
{   
    unsigned char y;
     unsigned char x;
     x = 10; // 工作10天
    y = 3*x, x < 30;
    printf("小明10天挣了%d元\n",y); // 输出,后面更具体地说明这段代码

    return 0;
}

编译,成功,乱码

不慌,略施小计

不过,我们并不能依靠这个解决我们的问题,就比如x并没有被约束

那应该怎么做呢?在C语言中,可以这样,加一个判断(以后会提到),这跟原问题有异曲同工之处。

什么是变量?

        我们前面说了那么多,那么回到主题上,什么是变量?C中的变量和数学中的一样吗?从前面的操作我们可以回答:相似但不相同。

        具体而言,我们同样可以在C语言中对变量进行赋值,如上x=30,以及操作如y = 3 \ast x,乃至大小x < 30比较。如果说在数学中,我们是让变量属于某个集合,使其具有这些东西,那么在C中,我们就是让变量属于某个数据类型,这种让变量属于某个数据类型的操作,可以格式化为

DataType\; variable

        这种操作,有一个专业的术语,称之为定义definition)。

        之前,我曾提过不必刻意规定y的具体值域,只需保证y能够存储结果值即可,你会发现在存储问题上两者就不相同,因为在数学中,存储是虚拟的,从某种程度上存在脑子里,而在C语言中,数据是在计算机中真实存在的,也可以说也在电脑“脑子”里。所以对于C语言里面的变量,其必然要与一块内存空间相关联,也可以说这块内存空间叫做这个变量。

        如果我们要计算y=3x,我们会先找到x,那么计算机也是类似的通过x找到其值(更进一步说,找到一块叫做x的内存地址的值),如此我们可以说:

A variable is a named piece of memory that we can use to store values. In order to create a variable, we use a statement called a definition statement.

变量是我们可以用来存储值的命名内存。为了创建变量,我们使用称为定义语句的语句。

注意:变量是内存,变量名是内存名

变量与赋值

        变量的赋值,并不像前面的那样简简单单,就比如y = 3 \ast x,换个位置,就会出错,不过这在数学上是可以的。

        这就涉及到赋值中的两端,我们称之为左值与右值:

左值与右值

        顾名思义,左值是赋值操作左边的部分,右值是赋值操作右边的部分。我们规定左值是待赋值的变量(一个内存空间,用于接收值),而不能是非变量,也即不能改变的量,在上面3\ast x就是一个非变量,虽然x是变量,但是3\ast x使成为了一个确定的值。而右值则没有太多限制。

实例化与初始化

        回到我之前的一个源码,我并没有在这里对x进行赋值,又把它赋值给了y,程序并没有报错,这是为什么呢?(当然,在数学中,这完全可以,因为这不过是一个数学表达式。但是经过前面的描述,你会发现,这不是一个数学表达式,或者说在C中称之为赋值更为贴切)。

        首先,我们要认识到一个点:

When the program is run, each defined variable is instantiated, which means it is assigned a memory address.

当程序运行时,每个定义的变量都被实例化,这意味着它被分配了一个内存地址。

        也就是说当我如此操作时,是直接取这个被分配的内存地址里面的数据(当然我给它赋值后也是如此),换句话说,我们将得到一个意想不到的值(这并不意味着错误,通常只是警告),这时x称之为未初始化变量(uninitialized variable),值得注意的是,初始化initialization)并不是等同说赋值(Assignment):

  • Initialized = The object is given a known value at the point of definition.

        初始化=在定义时被赋予一个值。

  • Assignment = The object is given a known value beyond the point of definition.

        Assignment=定义后被赋予一个值。

  • Uninitialized = The object has not been given a known value yet.

        未初始化=对象尚未被赋予值。

        另一个值得说明的是,有时,我们会说"Reassignment"(重赋值),指将一个新值赋予已经声明过的变量的过程,这意味着变量的当前值被新值替换。这在后面会进一步说明。

        下面是一个简单的代码说明:

// 声明一个变量
int a; // dataType varibale;
// 赋值
a = 10; // variable = value;
// 声明并初始化一个变量
int b = 10; dataType variable = value;

        在这里,几个我比较认同的Best Practice 是:尽量初始化变量,避免使用未经初始化的变量;对于变量,尽量单独定义,不要连续定义,以防出现忘了初始化某个变量。

声明与定义

        可以看到,在上面我使用了不同两种说法描述,这一过程:

        DataType\; variable

        声明(Declaration)与定义(Definition) 

        更严格地说,这就是定义,但是有时,也会看到说这是声明。声明就好比老板跟小明说你每天的工资是3元,但是,是不是就是另一回事了,而定义就好比跟小明签了个契约,工资啥的纸上都有。这说明定义相比于声明更加的具体和可靠,在C语言中定义也意味着分配内存。

        专业点可能如下:

         A declaration tells the compiler about the existence of an identifier and its associated type information.

        声明告诉编译器标识符的存在及其关联的类型信息。

        A definition is a declaration that actually implements (for functions and types) or instantiates (for variables) the identifier.

        定义是实际实现(对于函数和类型)或实例化(对于变量)标识符的声明。

        关于声明与定义,后面会结合其它语法更加深入讨论。

关于变量的其他说明

        关于变量,还有一些很多教程都会首先提到的一些东西,比如命名(基本上很多编程语言都一样),这些东西基本上就属于编程规范了。在C语言的变量基本要素中(数据类型、值、名、作用域),我将在后面讨论作用域的问题。

 关于基本数据类型的再探讨

        为什么要再探讨呢?因为在基本数据类型的那张表中,有一个地方,我并没有讨论过,那就是类型,类型何以重要,就凭数据类型可以简称类型!在那张表中,有三种数据类型(整型、实型和字符),不过读者可能发现,即使有这三种不同的类型,但是在上面的语境中,它们仍然不过是透明的,就比如在选择y的类型时,我们关注的是取值范围,unsigned\; charunsigned\; short都可以,这难免会让人有点困惑。

        让我们打个比方。将内存想象成一块土地,把数据类型当作一种建筑类型,而变量就是一个具体的建筑,显然建筑有很多种(数据类型多样),但构成建筑的原材料几乎类似(让我们抽象为0与1),向具体的建筑中放置原材料(赋数值,复杂一点的数据类型可能并不直接)当然可以,但是可能有点怪,就比如往一个办公楼里面放一吨的水泥,我们倾向于说给办公楼增加一层(让数据以合适的形式赋予特定的数据类型),所以我们可能会这样

unsigned\, \: char \: c \: = \, 'A';

        即赋予一个unsigned\: char类型的变量c字符 'A'值,但请注意,这并不意味着在c的内存中就是一个字符'A',而是二进制(01组合)的数值65,因为AASCII码值就是65。换句话说,上面的定义效果等同于

unsigned\, \: char \: c \: = \, 65;

         嗯?这是为什么呢?这就要归功于=(赋值运算符)的作用了,它会将右值转换为左值的数据类型(赋值转换),这就相当于装修工人,把原材料转换成建筑里面的东西。

        值得注意的是,尽管这么说,但是在计算机内存中都只是0和1而已,在计算机内存中并不存在数据类型。数据类型是编程语言在内存上抽象的“建筑”,拥有对里面的数据的解释权(这一块是办公区,这一块是……)。

(二)常量

        在数学中,我们也经常用到这个词,就比如大名鼎鼎的\pi = 3.1415.....。不过并不等同于数学中的常量,在编程中,常量应该更确切的说是在预期的时间段内不会改变的值,换句话说,在程序运行时不变的量。

        好比说,小明在一开始的工资是个常量3,不过可能过了一星期就变成了7。这时候我的程序就要改动了。

        在C语言中有三种定义形式的常量

宏常量

一般定义在C文件的上部,单独占一行

示例:

#define 符号标识符(宏名) 常量(数值或表达式)
#define PI 3.14

定义时一行写完,一般不出现分号

        由宏定义方式定义的符号标识符与其对应常量具有等价关系,在程序编译预处理时进行替换,不会做多余地改变,应当注意的是,在输出语句中的符号标识符不会进行替换,此时的符号标识符不是宏常量,而是字符串

        下面举个例子        

找到i文件,可以发现变量被替换了,但是字符串里面的没有

        关于宏常量还有很多有趣的地方后面讨论。

const 常量

        const 常量与变量相比显著多了一个const,与宏常量相比,const常量具有数据类型,const常量更像是常量,宏常量只不过是替换。

const 数据类型 常量名=值; // 也可以 数据类型 const 常量名 = 值;
const int PI = 3.14;

        另一个重要的点是const常量必须初始化,不然后面再赋值就是错误,因为const定义后就是只读的。        

枚举常量与枚举类型

        如果还记得我之前所说的对变量的取值范围做限制的特例,这就是。

        所谓枚举,就是可以一个一个数,它并不像short等有6千多取值可能(当然也可以数),不过枚举类型的变量的取值只有你定义时写出的枚举值个数个。

         举个例子,如下,这个枚举类型只有7种取值

// enum [枚举类型名]{枚举值列表} 定义一个枚举类型
enum Weekdays {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

       也就是说enum Weekdays这个枚举类型定义的变量只能赋予这7种值。诶,这就有点怪了,和之前的数据类型相比,感觉好复杂,下面才是定义变量。

// enum 枚举类型名 变量 定义一个枚举变量
enum Weekdays today;

        给枚举变量赋值:可以使用枚举值来给枚举变量赋值。

today = Monday;

        使用枚举变量:可以在表达式中使用枚举变量。编译器会根据枚举值自动替换枚举变量。

printf("Today is %d\n", today); // 输出 "Today is 1"

        注意:枚举类型的第一个枚举值默认为0,后续的枚举值依次加1。例如,在上面的例子中,Sunday是第一个枚举值,其值为0;Monday是第二个枚举值,其值为1,以此类推。

        当然也可以自定义整数顺序,如下:        

enum Weekdays {Sunday = 7, Monday, Tuesday = 9, Wednesday, Thursday, Friday, Saturday};

        没有显式说明的枚举值默认就是前面的枚举值加1。

(三)字面量(变量的值)

        字面量是变量的值表现形式,比如1234‘a’等这些确定的值,所以字面量也可称为字面常量(literal constant)

literal (also known as a literal constant) is a fixed value that has been inserted directly into the source code.

文字(也称为文字常量)是直接插入源代码的固定值。

        在程序中,我们将在不同情况下使用到字面量,其中一种最常见的情况下就是变量的赋值:

int a = 1;

        这里要讨论的,不是将1变成其它值如2,而是其它形式的1,比如0X01(十六进制的1),即值的表现形式。

字面整型(数)常量

1、值的进制

        整数常量(integer constant)可表示为常见的十进制数字、八进制数字、十六进制记数法乃至二进制的数字。

        以下为128的不同进制表示

    int d = 128;            // 十进制
    int h = 0x80;          //  十六进制,以0x或0X开头
    int o = 0200;         //   八进制,以0开头
    int b = 0B10000000;  //    以0b或0B开头
2、值的类型

        由于所定义的整数常量最终将用于表达式与声明中,因此它们的类型非常重要,当常量的值被确定时,常量的类型也会被同时定义。

        对于一个整数,不加修饰的,都默认为int类型,如下在vscode中,当鼠标悬浮在整数上时

        以上只是部分说明,可以看到字符常量默认也是int类型。

        也可以利用后缀显式定义常量的类型。

整数常量后缀(大小写皆可)

类型

U

unsigned int

L

long

UL

unsigned long

LL

long long

llu

unsigned long long

实型(浮点)常量

实型常量是指带有小数点的数,如0.2,所以下面形式的实型常量也是合法的

float a = .125; // ==0.125 不写整数部分
float b = 10.;  // == 10.0 不写小数部分

浮点常量可采用十进制或者十六进制记数法(C99标准引入)

// 十进制
float a = 64.25;
// 十进制指数形式 (整数或小数)e(E)(整数)
float b = 642.5e-1 // 642.5 x 10^(-1) = 64.25
// 十六进制记数法,只能是科学记数法的形式,和整型一样加上0x或0X前缀,用p或P代替e,用 2 的幂代替 10 的幂
float b = 0x10.1p2; // (1 x  16^1 + 0 x 16^0 + 1 x 16^(-1) ) x 2^2 = 64.25

实型常量隐含按双精度类型(double)处理,如果要显式声明其为单精度常量后可跟F或f

float a = 3.14F;

与整数常量类似的长双精度常量后缀可加用L或l。

long double a = 3.14L;

浮点常量示例:

浮点常量

10.0

10

2.34E5

2.34x105

67e-12

67.0x10-12

字符常量

        用 ''括起来的一个ASCII字符,如'a'。特别的,对于有些ASCII字符,需要使用以\为开头标志的转义字符。以下是C语言中常见的转义字符及其含义的表格形式:

转义字符

含义

ASCII码(十进制)

\0

空字符(NULL)

0

\t

制表符(HT)

9

\b

退格符(BS)

8

\n

换行符(LF)

10

\r

回车符(CR)

13

\f

换页符(FF)

12

\a

响铃符(BEL)

7

\v

垂直制表符(VT)

11

\\

反斜线符

92

\'

单引号

39

\"

双引号

34

\?

问号

63

\ddd

任意字符

三位八进制

\xh[h..]

任意字符

二位十六进制

三、数据类型转换

        考虑以下一个程序运算场景:

int a = 12 + 3.14;
// 12 默认为int类型
// 3.14默认为double类型
  • 不同类型的变量怎么相运算?(数据类型自动转换)
  • 赋给一个变量与其数据类型不相同的值时怎么处理?(赋值数据类型转换)

        这就涉及到数据类型的转换问题,只有统一数据类型才能相操作。

(一)类型自动转换

        类型自动转换是在运算时系统自动完成的,转换规则为级别低的类型向级别高的转换,即存储位数少的向存储位数多的转换

        当一个运算符的几个操作数类型不同时,就需要通过一些规则把它们转换为某种共同的类型。一般来说,自动转换是指把“比较窄的”操作数转换为“比较宽的”操作数,并且不丢失信息的转换,例如,在计算表达式 f+i 时,将整型变量 i 的值自动转换为浮点型(这里的变量 f 为浮点型)。

(二)赋值转换

        在赋值运算时,当赋值运算符两边的操作数类型不一致时,将右侧操作数的运算结果类型转换为左侧的数据类型:

  1. 整型给实型,整数部分不变,以浮点数形式储存到变量中
  2. 实型给整型,舍弃小数部分,不四舍五入
  3. 字符型给整型,数值不变,将字符变量的8个二进制位存入整型变量的低8位中
  4. 整型给字符型,将整型低8位存入字符型变量中
  5. float给double,数值不变,位数增加
  6. double给float,截取double型的前7位有效数字
  7. 当单双引号''中的字符不止一个且不是转义字符,赋值给一个字符变量时,取后八位,一般即最后一个字符

(三)强制类型转换

//(dataType)(value || expression)
int a = (int)3.14;
int b = (int)(3 + 3.14);

(四)数据溢出

        每一种基本数据类型,尽管大小不一,但是所占空间是确定的,如果赋予其超过其范围的数据,就会有问题,就像往一个无盖的1m正方体盒子里面注超过1立方米的水,就会溢出。

整数溢出

整数溢出可以分为有符号整数溢出和无符号整数溢出。

  • 有符号整数溢出

    • 当一个有符号整数增加到最大值(通常是INT_MAX)后再增加,或者减少到最小值(通常是INT_MIN)后再减少时,会发生溢出。
    • 在这种情况下,数值将“环绕”(wrap around),从最大值变到最小值,或从小到最大。
    • 这种行为在C标准中是未定义的(undefined behavior),意味着编译器可以自由选择如何处理这种情况,这可能导致难以预料的程序行为。
  • 无符号整数溢出

    • 无符号整数没有负数的概念,它们只表示非负数。
    • 当无符号整数达到其最大值后再次增加时,它会从0开始计数,这也是“环绕”。
    • 不同于有符号整数,无符号整数的这种行为在C语言中是定义明确的,它将执行模运算。

        以下为一个简单的变量溢出测试,其中char是 有符号且最大可表示127,unsigned char最大可表示255。可以发现unsigned char类型的变量的确有环绕现象。

        至于为什么c是-1,这就涉及到数值的存储。255二进制表示为1111 1111,赋值时直接存在c中,而内存中的数据一般是默认为真值的补码形式,恰好char类型是有符号的,1111 1111被解释为-1的补码。

 

浮点数溢出

浮点数也可能发生溢出,但通常称为上溢(overflow)或下溢(underflow)。当浮点数的值太大或太小而不能表示时,可能发生以下情况:

  • 上溢:数值太大,被表示为无穷大(+INF 或 -INF)。
  • 下溢:数值太小,接近于零,可能被表示为零。

浮点数的溢出,可参考以下示意图,这里不多展开了。

来源: 15 张图带你深入理解浮点数-CSDN博客
来源: 数据运算 浮点数表示与加减运算_浮点数加法溢出处理-CSDN博客

 

四、表达式与运算

        表达式(expression)是由一系列的常量、标识符和运算符表示的值操作。如:

a = 1 + 3;
b = -5;

        操作数(operant)是运算符作用于的实体,是表达式中的一个组成部分,它规定了指令中进行数字运算的 ;操作数是相对于表达式而言的。

a = 1 + 3; // 操作数:1、3
b = -5; // 操作数: 5
c = a + b; // 操作数:a、b

        表达式是操作数和操作符的组合

(一)算术表达式

        用于进行数学运算,如加、减、乘、除等。例如,a + b 表示将变量 ab 的值相加。

运算符

说明

*

乘法

/

除法,要避免除0

%

模运算,需要整数操作数

+

加法

-

减法

+

(一元)

正号

-

(一元)

负号

(二)逻辑表达式

        用于进行逻辑运算,并且产生一个int类型的值。如果表达式为真,这个值为1,不然为0。运算符&&||的操作数计算次序是从左到右,如果左操作数的值已经能决定整个计算的结果,那么右操作数就根本不会计算,这称为逻辑短路

运算符

说明

&&

逻辑与

||

逻辑或

!

逻辑非

// 对于任何数值,如果不是0,则相当于true,否则为false
1 && 0 => false
1 || 0 ==> true
// 短路现象
a = 1;
b = 3;
a > 3 && b = 4; // b的值不会改变,因为a > 3就已经决定了这个表达式为false

(三)关系表达式

用于比较两个值之间的关系,并且产生一个int类型的值。如果指定的关系成立,这个值为1,不然为0

运算符

说明

>

大于

>=

大于等于

<

小于

<=

小于等于

==

等于

!=

不等于

(四)赋值表达式

        用于将一个值赋给一个变量。例如,a = b 表示将变量 b 的值赋给变量 a

运算符

示例

相当于

=

a = b

a = b

+=

a += b

a = a+b

-=

a -= b

a = a-b

/=

a /= b

a = a / b

%=

a %= b

a =  a % b

&=

a &= b

a = a & b

|=

a |= b

a = a | b

^=

a ^= b

a = a ^b

>>=

a >>= b

a = a >> b

<<=

a <<= b

a = a << b

        除了第一个运算符,其它的称之为复合运算符,与其等价运算相比,执行速度更快

(五)其它运算符

运算符

说明

示例/说明

++

自增运算符(使用后缀,表示先使用其值后自增1,前缀相反)

a++++b

--

自减运算符(使用后缀,表示先使用其值后自减1,前缀相反)

a--–-b

sizeof

以字节为单位,计算操作数的空间大小

sizeof(a)sizeof(int)

sizeof a

?:

表达式1 ? 表达式2  : 表达式 3

当表达式1为真,执行表达式2,否则表达式3

,

表达式1,表达式2

顺序处理两个表达式,第二个表达式的类型和值作为整个表达式的结果

显式强制类型转换运算符

(类型标识符)(表达式或变量)

(int)a(int)(3 + 3.14)

 



敬读者:        

        由于文章篇幅过长,可能导致叙述逻辑的不严密、不连贯,还请读者体谅。另外,本文仅作为个人的理解,不代表任何专业性的见解。不得不承认,文章在某些地方可能有划水现象,希望读者自我甄别。

标签:常量,int,数据类型,笔记,C语言,枚举,表达式,变量
From: https://blog.csdn.net/m0_63684047/article/details/140105941

相关文章

  • 【机器学习算法基础】(基础机器学习课程)-07-朴素贝叶斯算法-笔记
    一、朴素贝叶斯算法原理        朴素贝叶斯(NaiveBayes)是一种基于贝叶斯定理的简单而强大的分类算法,尤其适用于文本分类问题,如垃圾邮件检测、情感分析等            二、朴素贝叶斯算法对新闻进行分类案例  1.数据准备假设......
  • Python学习笔记27:进阶篇(十六)常见标准库使用之质量控制中的代码质量与风格第一部分
    前言本文是根据python官方教程中标准库模块的介绍,自己查询资料并整理,编写代码示例做出的学习笔记。根据模块知识,一次讲解单个或者多个模块的内容。教程链接:https://docs.python.org/zh-cn/3/tutorial/index.html质量控制质量控制(QualityControl,QC),主要关注于提高......
  • Vue3实战笔记(64)—Vue 3自定义指令的艺术:实战中的最佳实践
    文章目录前言一、一些简单的Vue3自定义指令超实用案例总结前言书接上文,在Vue3中,自定义指令是一种强大的工具,允许我们扩展HTML元素的功能。通过自定义指令,我们可以创建可重用的行为,并将它们绑定到任何元素上。下面,本文备份一些简单的Vue3自定义指令超实用案例,并解释......
  • 《智能计算系统》第五章 编程框架原理(上)课程笔记
    《智能计算系统》第五章编程框架原理(上)课程视频链接:https://www.bilibili.com/video/BV1Ei421i7Rg本文源自于B站国科大计算所智能计算系统课程官方账号所公开上传的视频,在原有视频之上,提取了关键帧、将音频转成了文字并进行了校正,以便学习使用。在此,也感谢国科大计算所智能......
  • Java 基本数据类型和引用数据类型有什么区别?
    在Java世界里,数据类型是构建程序的基石,它们决定了变量可以存储什么类型的值以及如何操作这些值。Java的数据类型大致可以分为两大类:基本数据类型(PrimitiveDataTypes)和引用数据类型(ReferenceDataTypes)。理解它们之间的区别,对于编写高效、健壮的Java代码至关重要。现在,我们......
  • C语言命名规范
    C语言命名规范在C语言中,命名规范对于代码的可读性和可维护性至关重要。以下是一些常见的C语言命名规律和建议变量命名变量名应该具有描述性,清晰地表达变量的用途或含义。变量名使用小写字母和下划线(snake_case)的组合,例如intmy_variable;。避免使用单个字符作为变量名,除非......
  • 学习笔记485—Excel技巧:一键将文本数字转换为数值
    Excel技巧:一键将文本数字转换为数值在使用Excel进行数据处理时,经常会遇到数据格式不匹配的问题。特别是当从外部导入数据或手动输入数据时,数字可能会被误识别为文本格式,这在进行数据计算和分析时会带来诸多不便。幸运的是,Excel提供了一些便捷的方法,可以帮助我们一键将文本转换为......
  • 解析Kotlin中扩展函数与扩展属性【笔记摘要】
    1.扩展函数1.1作用域:扩展函数写的位置不同,作用域就也不同扩展函数可以写成顶层函数(Top-levelFunction),此时它只属于它所在的package。这样你就能在任何类里使用它:packagecom.rengwuxianfunString.method1(i:Int){...}..."rengwuxian".method1(1)扩展函数......
  • [学习笔记] 动态开点权值线段树合并 - 数据结构
    权值线段树例题【模板】普通平衡树#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+1;intn,val[N],opt[N],num[N],cnt,len,san[N],m[N],rnk[N];unordered_map<int,int>dfn;structWeightedSegmentTree{ #definels(id<<1) #define......
  • c语言基础3
    [1]运算符1.1逻辑运算符&&逻辑与:全真则真,一假则假||逻辑或:一真则真,全假则假!逻辑非:非真则假,非假则真0为假1为真printf("%d\n",2>3);//0printf("%d\n",22>3);//1printf("%d\n",12>3&&8<6);//0printf("%d\n",12>3||8<......