运算符&表达式&数据类型

1. 变量和基本数据类型

1.1变量类型概念

变量就是在程序中发生变化的量,变量有类型。

变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式。

1字节(byte)=8位(bit)

1.2定义格式

存储类型数据类型变量名;

例如:(auto)inta;

存储类型:变量存储的位置。

数据类型:名字字节取值范围

类型

存储大小

值范围

char

字符类型

1 字节

-2^7 到 (2^7-1)

unsigned char

无符号字符类型

1 字节

0 到 (2^8-1)

int

整数类型

4 字节

-2^31 到 (2^31-1)

unsigned int

无符号整数类型

4 字节

0 到 (2^32-1)

short

短整型

2 字节

-2^15 到 (2^15-1)

unsigned short

无符号短整形

2 字节

0 到 (2^16-1)

long

长整型

4 字节

-2^31 到 (2^31-1)

unsigned long

无符号长整形

4 字节

0 到 (2^32-1)

float

单精度浮点型

4字节

有效数据6-7位

double

双精度浮点型

8字节

有效数据15-16位

64位操作系统:long类型是8字节

例子:

1.3初始化格式

(1) 可以定义时初始化

inta=0;

(2) 也可以先定义然后初始化

inta;

a =0;

1.4局部变量全局变量

(1)生命周期:变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。也就是存活的周期时间。时间维度。

(2)作用域:变量可以起作用的范围。空间维度。

(3)内存大致分配为五个区域:

局部变量、全局变量的区别?(面试题)

局部变量

全局变量

1. 定义位置

函数体内部

函数体外部

2. 存储位置

栈区

全局区

3. 生命周期

同函数体共存亡

同整个程序共存亡

4. 作用域

作用于函数体内部

作用域整个程序

5. 初值

未初始化,值为随机值

未初始化时,值为0

当我们在定义变量时,选择正确合适的数据类型,既可以提高空间利用率,同时也可以避免溢出等问题的出现。

未初始化的局部变量为随机值

2. 常量

2.1概念

在程序中不会发生变化的量,存在常量区。

2.2分类

2.2.1字符型常量

类型为char,从ascii表中找的的字符都是字符常量,不可以改变。用单引号括起来的就是字符常量,例如'A'。

类型

存储大小

值范围

char

字符类型

1 字节

-128 到 127

unsigned char

无符号字符类型

1 字节

0 到 255

signed char

带符号字符类型

1 字节

-128 到 127

原码、反码和补码:

(1) 最高位表示符号位,正数是0,负数是1。

(2) 正数原码、反码和补码都是一样的。

(3) 负数要用补码来计算:

● 原码就是在数值前面直接加符号表示

● 反码等于原码的符号位不变其余按位取反

● 补码等于反码加一

例如:-5

原码:1000 0101

反码:11111010补码:11111011

补码:

用''括起来的就是字符常量:

'a'字符a

'\0'空字符

' '空格

'\n'换行

例子:

#include <stdio.h>

int main()
{
	//可以把字符常量赋值给字符变量
	char ch = 'a'; //定义了一个char类型名为ch的变量并赋值为'a'
	ch = 'b';	   //重新对ch变量赋值为'b'
	char ch2 = ch; //定义了一个char类型名为ch2的变量并赋值为了ch的值

	printf("%c %c\n", ch, ch2); //分别打印两个变量ch和ch2
	printf("%c\n", 'A');		//打印字符'A'
	printf("%c\n", 65);		//用ASCII值打印'A'
	printf("%c\n", '\x41');	 //用十六进制的ASCII值打印'A'
	printf("%c\n", '\101');  //用八进制的ASCII值打印'A'
	return 0;
}

打印结果:

因为C规定转义字符'\x41'中\是转义字符引导符,后跟一个x表示x后面的数字是十六进制表示法,用' '括起来表示一字节ASCII码。\转义符后面加数字代表转义成八进制的字符,后面的数字是八进制。

2.2.2字符串常量

用""括起来的是字符串,'\0'是字符串结尾的标志

"hello"字符串后面有个'\0'

printf("%s \n", "hello world");

2.2.3整型常量

整型就是类型为整数的常量,包括从负数到零到正数的所有整数。可以用二进制、八进制、十进制和十六进制表示。

#include <stdio.h>

int main()
{
	int a = 15; //定义了一个数据类型为int的名叫a的变量,并且赋值为常量15

	printf("%d\n", 15);				  //十进制
	printf("%d\n", 0b1111);		//二进制
	printf("%d\n", 017);			//八进制
	printf("%d\n", 0xF);			//十六进制
	printf("%d\n", a);				   //打印保存了15的变量

	return 0;
}

打印出来都是15

2.2.4浮点型常量

浮点型常量就是类型为浮点的常量,包括从负数到零到正数所有的浮点数。

floatdouble

2.2.5指数常量

用科学计数法表示

3*10^8-->3e8

2*10^-12-->2e-12

2.2.6标识常量(宏定义)

宏定义:起到标识作用的

(1)只是单纯的进行文本替换,在预处理的时候进行。

(2)遵循标识符的命名规则

(3)一般大写表示

格式:#define宏名常量或表达式

特点:只能单纯替换,不要进行手动运算(原样替换,替换完了再计算)

例子:

练习:

#include <stdio.h>
#define N 2
#define M N + 2
#define SUM N + M / 2 + 1   //2 + 2 + 2 / 2 +1

int main()
{
	int a = SUM;  //2 + 2 + 2 / 2 +1
	printf("%d\n", a);  //6
	return 0;
}

3. 运算符和表达式

(1) 所谓表达式是指由运算符、运算量和标点符号组成的有效序列,其目的是用来说明一个计算过程。表达式可以独立形成语句,该语句称为表达式语句。

表达式语句的一般形式为:

表达式;

(2) 运算符按功能分为:算数运算符、赋值运算符、关系运算符、逻辑运算符、位运算符和其他运算符

3.1 算术运算符: + - * / % ++ --

(1) /: 整数相除,向下取整

#include <stdio.h>

int main()
{
	int a = 3 / 2;
	float b = 3 / 2;
	float c = 3.0 / 2;

	printf("a = %d\n", a);  //a = 1
	printf("b = %f\n", b);  //b = 1.000000
	printf("c = %f\n", c);   //c = 1.500000

	return 0;
}

只针对于常量,不针对于变量

#include <stdio.h>

int main()
{
	float a = 3, b = 2;
	printf("%f\n", a / b);  //1.500000
	return 0;
}

(2) %: 只能用于整数运算,取余

10%3 = 1

12%10 = 2

练习:将12345的个十百千万位分别输出到终端。

#include <stdio.h>

int main()
{
	printf("%d\n", 12345 % 10);
	printf("%d\n", 12345 / 10 % 10);
	printf("%d\n", 12345 / 100 % 10);
	printf("%d\n", 12345 / 1000 % 10);
	printf("%d\n", 12345 / 10000);

	return 0;
}

(3) ++: 自增

int a=0;

a++; //相当于 a=a+1;

++a; //相当于 a=a+1;

#include <stdio.h>

int main()
{
	int a = 1;
	int b = 1;
	a++;   //a=a+1  ==>a=2
	++b;  //b=b+1 ==> b=2
	printf("%d %d\n", a, b);  //2 2

	return 0;
}

(4) -- :自减

a--;

--a;

都相当于a=a-1;

和打印语句结合:

printf("%d\n",a++); //++在后,先打印,再自加

//先执行printf("%d\n",a); 再执行a=a+1;

printf("%d\n",++a); //++在前,先自加,再打印

//先执行a=a+1; 再执行printf("%d\n",a);

#include <stdio.h>

int main()
{
	int a = 1;
	int b = 1;
	
	printf("%d\n",a++); // 1
	// 因为相当于先执行printf("%d\n",a);  再执行a=a+1; 
	printf("%d\n",a);  //2

	printf("%d\n",++b);  //2
	//因为相当于先执行b=b+1; printf("%d\n",b);
	printf("%d\n",b);  //2

	return 0;
}

3.2 赋值运算符: = += -+ *= /=

int a=1;

(1) int b = ++a; //先自加然后再赋值

相当于:先执行a=a+1; 再执行 b=a;

(2) int b= a++; //先赋值再自加

相当于: 先执行 b=a; 再执行 a=a+1;

例如:

z = ++x + y++;

相当于:

x=x+1;

z=x+y;

y=y+1;

(3) a+=2;

相当于:a=a+2;

#include <stdio.h>

int main()
{
	int a = 1;
	a += 2;  //a=a+2
	printf("%d\n", a);  //3

	return 0;
}

练习1. 以下程序输出结果是 31

#include <stdio.h>
int main(int argc, char *argv[])
{
    int a = 10;
    int b = a++;  //b=10, a=11
    int c = a + b; //c=21 ,b=10,a=11
    int d = (b++) +c; //d=10+21=31, b=11
    printf("d =%d \n",d);
    return 0;
}

2. 以下程序输出结果是 34

#include <stdio.h>
int main(int argc, char *argv[])
{
    int a = 10; 
    int b = ++a;    //a=11, b=11   
    int c = a + (b++);  //c = 11+11=22, b=12
    int d = b + c;    //d=12+22=34
    printf("%d\n", d);
    return 0;
}

3.3关系运算符:><<=>===!=

用来判断两者的关系,返回1或0。

运算符

名称

示例

功能

缩写

<

小于

a<b

a小于b时返回真,否则返回假。

LT

<=

小于等于

a<=b

a小于等于b时返回真,否则返回假。

LE

>

大于

a>b

a大于b时返回真,否则返回假。

GT

>=

大于等于

a>=b

a大于等于b时返回真,否则返回假。

GE

==

等于

a==b

a等于b时返回真,否则返回假。

EQ

!=

不等于

a!=b

a不等于b时返回真,否则返回假。

NE

#include <stdio.h>

int main()
{
	int a = 2, b = 3;

	printf("%d\n", a < b);  //1
	printf("%d\n", a >= b); //0
	printf("%d\n", 100 % 10 != 0); //0
	printf("%d\n", 100 % 10 == 0);   //1

	return 0;
}

3.4逻辑运算符&& || !

C语言中非0代表真,0代表假

3.4.1&&(逻辑与)

全真则真,一假则假。

全是真的才是真,只要有假就是假。

int a = 2, b = 3;
	printf("%d\n", 1 && 1); //1
	printf("%d\n", 1 && 0); //0
	printf("%d\n", 0 && 1); //0
	printf("%d\n", 0 && 0); //0
	printf("%d\n", a && b); //1
	
    int x = 100;
	printf("%d\n", 2 < x && x < 10); // 判断2<x<10是否满足

3.4.2||(逻辑或)

一真则真,全假则假。

只要有真的就是真,全都是假的才是假。

int a = 2, b = 3;
	printf("%d\n", 0 || 0); //0
	printf("%d\n", 1 || 0); //1
	printf("%d\n", 0 || 1); //1
	printf("%d\n", 1 || 1); //1
	printf("%d\n", a || b); //1

	int x = 100;
	//满足x<0或者 x>10
	printf("%d\n", x < 0 || x > 10);  //1

3.4.3!(逻辑非)

非真为假,非假为真

printf("%d\n", !0);  //1
	printf("%d\n", !1); //0
	printf("%d\n", !(2 < 3));  //0

3.4.4短路法则/截断法则

逻辑或||运算中:如果前面的表达式为真,则后面的表达式不执行。

逻辑与&&运算中:如果前面的表达式为假,则后面的表达式不执行。

例1:

#include <stdio.h>
int main()
{
    int a=5,b=6,c=7,d=8,m=2,n=2;
    int r=(m=a<b)||(n=c>d); //m=1,n=2,r=1
    printf("%d  %d %d",m,n,r);
}

用到了短路法则,逻辑或||前面公式判断为真后面不执行,结果为真。

例2:

#include <stdio.h>
int main()
{
    int a=5,b=6,c=7,d=8,m=2,n=2;
    int r=(m=a>b)&&(n=c>d);  //m=0, n=2, r=0
    printf("%d  %d  %d",m,n,r);
}

练习:给出一个年份,判断是平年还是闰年。如果是润年打印1,平年打印0。

(提示:判断闰年还是平年,闰年且闰年二月份以上比平年多一天。普通年份除以4,有余数是平年,对于整百的年份,比如2100年,要除以400,有余数就是平年,整除就是闰年。)

思路,可以设置一个标志flag来接收平年还是闰年。然后用逻辑运算去判断平年还是闰年。最后打印flag。

结果:闰年打印1,平年打印0。

#include <stdio.h>
#define YEAR 1999
int main()
{
	int flag = 0;
	flag = (YEAR % 100 != 0 && YEAR % 4 == 0) || (YEAR % 400 == 0);
	printf("闰年为1,平年为0: %d\n", flag);

	return 0;
}

3.5运算符&|^~<<>>

含义

C语言

按位与

a&b

按位或

a|b

按位异或

a^b

按位取反

~a

左移

a<<b

右移

a>>b

无符号右移

/

注意:负数都是用补码进行运算的

3.5.1&(位与)

全1则1,有0则0。

例如:

11110101

&11111101

11110101

3.5.2|(位或)

有1则1,全0则0。

例如:

11110101

| 11111101

1111 1101

3.5.3^(异或)

不同为1,相同为0。

例如:

11110101

^ 11111101

00001000

3.5.4~(取反)

按位取反,0变成1,1变成0。

原码 反码 补码

正数:本身本身本身

负数:本身符号位不变其余位按位取反反码+1

~15

正数原码:00001111

正数补码:00001111

取反~:11110000

~-1:

原码:10000001

反码:11111110

补码:11111111

~:00000000

3.5.5<<(左移)

左移几位,右边补几个零。

8<<2 = 32:1000左移两位得到100000

-5<<3:

-5原码:10000101

反码:11111010

补码:11111011

<<3:(111)1101 1000(-40)

10100111(符号位不变,其余按位取反)

10101000 (再上一步基础上+1,得到-40的原码)

3.5.6>>(右移)

右移几位,左边补几个符号位,正数补0负数补1。

8>>2=2

==>0000 0010

-5>>3:

-5原码:10000101

反码:11111010

补码:11111011

>>3: 1111 1111(补码)

10000000

10000001(-1的原码)

3.5.7公式置零公式

置一公式:a | (1<<n)

置零公式:a&(~(1<<n))

3.6特殊运算符

3.6.1三目运算符

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

先求解表达式1,如果结果为真(非0)就把表达式2的值作为整个表达式的取值,否则(表达式1结果为假也就是0)那么讲表达式3的值作为整个表达式的结果。

练习:判断以下打印结果

int num1 = 10, num2 = 20;
int res = num1 > num2 ? num1++ : num2++;
printf("num1=%d  num2=%d   res=%d\n", num1, num2, res);

//10 21 20

2.6.2sizeof()

sizeof运算符运算的格式:

sizeof(数据类型或变量名);

注意:32位系统long是4字节,64位系统是8字节。

3.7 优先级

口诀: 单算移关与 异或逻条赋

从右向左单条赋

练习: 结合宏定义三目运算符实现求两个数的差

#include <stdio.h>

/* 方式1:三目运算符结合宏定义 */
#define M 10
#define N 5
#define DIFF M > N ? M - N : N - M

/*方式2:三目运算符结合宏函数*/
#define DIFF_FUN(a, b) a > b ? a - b : b - a

int main()
{
	printf("%d\n", DIFF); //10 > 5 ? 10 - 5 : 5 - 10

	printf("%d\n", DIFF_FUN(3, 6)); //调用宏函数
	//3 > 6 ? 3 - 6 : 6 - 3
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值