C语言初阶 *** 作符学习笔记

C语言初阶 *** 作符学习笔记,第1张

*** 作符初阶
  • 1.算术 *** 作符
  • 2.移位 *** 作符
  • 3.位 *** 作符
  • 4.赋值 *** 作符
  • 5.单目 *** 作符
  • 6.关系 *** 作符
  • 7.逻辑 *** 作符
  • 8.条件 *** 作符
  • 9.逗号表达式
  • 10.下标引用、函数调用和结构成员

1.算术 *** 作符

算术 *** 作符包括加+,减-,乘*,除/,取模%。
针对这几种 *** 作符,加减乘和数学里的算术规则一致,除法在浮点数计算时,需要注意一下。例如:

int main()
{
	float c = 3.14f;
	float a = 3 / 5;
	float b = 3.0f / 5;
	printf("%f %f %f", a, b, c);
	return 0;
}

以上代码,我们先从第一行分析,由于c是单精度浮点型变量,当我们初始化时,不能单单只给数字3.14,因为小数是默认为双精度浮点数的,因此我们需要在小数后面加上f,代表浮点数3.14为单精度浮点数;接着分析第二行和第三行,这两行区别在于3和3.0f,在运行上有如下区别:

可以发现,当除号两边都为整数时,求得的也会是个整数,然后以浮点数形式打印出来,因此得出结论,当初始化浮点数变量时,在除号两端至少要有一个是浮点数形式的数字,且单精度浮点数数字后要加f
除法说完,说一下取模。取模也叫取余,就是取余数,例如:5%3=2,意思为5对3取余数等于2,这里需要注意的是取模两端必须为整数

2.移位 *** 作符

移位 *** 作符分为<<(左移操作符),>>(右移 *** 作符)。
左移 *** 作符:左移 *** 作符的移动规则是高位抛弃,低位补0。因为是移位 *** 作符,所以需要搞清楚移的是什么位。这里可以说明移动的是二进制位。而整数的二进制表示形式有三种,原码/反码/补码。正整数的原码,反码,补码相同,负数的原码是直接写出的二进制表示形式,反码是符号位(最高位)不变其他位按位取反,补码为反码加1;计算机内存里存放的是整数的二进制补码,因此移位 *** 作符作用对象也是补码。举个例子:
正数:
//15
//00000000000000000000000000001111–>原码,反码,补码
负数:
//-1
//10000000000000000000000000000001–>原码
//11111111111111111111111111111110–>反码
//11111111111111111111111111111111–>补码
那么15左移一位意为将15的二进制补码整体左移一位,高位抛弃,低位补0,得到//00000000000000000000000000011110,化为十进制为30,在测试了几组数据之后可以发现左移一位就是给数字乘2
右移 *** 作符:右移 *** 作符分为两种,逻辑右移和算术右移,这两种方式的区别在于:算术右移规则是低位抛弃,高位补符号位;逻辑右移的规则是低位抛弃,高位补0;而目前大多数情况都采用的是算术右移,具体的移动形式和左移类似。
这里需要说明的是,移位 *** 作符移动的位数必须是整数,且不为负数

3.位 *** 作符

位 *** 作符分为三种,&(按位与),|(按位或),^(按位异或),这里的位 *** 作符同样是对二进制补码进行 *** 作的。
&(按位与),举例来说吧:
//15
//00000000000000000000000000001111
//10
//00000000000000000000000000001010
//15&10
//00000000000000000000000000001010
通过例子得出:按位与是将两个数的二进制补码按位对比,同为1,则得1,其他都为0
|(按位或),同样的例子:
//15
//00000000000000000000000000001111
//10
//00000000000000000000000000001010
//15|10
//00000000000000000000000000001111
通过例子得出:按位或是将两个数的二进制补码按位对比,同为0,则为0,其他都为1
^(按位异或),也是同样的例子:
//15
//00000000000000000000000000001111
//10
//00000000000000000000000000001010
//15^10
//00000000000000000000000000000101
通过例子得出:按位异或是将两个数的二进制补码按位对比,相同为0,相异为1

4.赋值 *** 作符

赋值 *** 作符分为=,+=,-=,*=,/=,%=,<<=,>>=,&=,|=,^=;
赋值(=),很易懂,例如:a=6,意为将6赋予a;
复合赋值使用方法是很类似的,例如a+=b意为将a+b赋予a;a<<=b意为将a左移b位得到的值赋予a;a&b意为a按位与b得到的数赋予a;

5.单目 *** 作符

d幕 *** 作符分为:!(逻辑反 *** 作),-(负值),+(正值),&(取地址),sizeof(求大小),~(按位取反),–,++,*(间接访问 *** 作符又叫解引用 *** 作符),(类型)(强制类型转换)。
!(逻辑反 *** 作),意思为让假变为真,真变为假,C语言里非0为真,0为假,例如:

int main()
{
	int a = 1;
	if (a)
		printf("b");
	else
		printf("c");
	return 0;
}

该程序输出应为b,但是当判断条件前加!后,即 if (!a),该程序输出就位c了。
-(负值),+(正值)这里的+作用不大,-代表取相反数
&(取地址),*(间接访问 *** 作符又叫解引用 *** 作符):取地址 *** 作符常常与解引用 *** 作符连用,例如:

int main()
{
	int a = 1;
	int* pa = &a;
	*pa = 10;
	printf("%d", a);
	return 0;

int * pa = &a是将变量a的地址存放在指针变量pa中,✳代表pa为指针变量,int代表指针指向的对象为int类型,可以通过解引用 *** 作符✳访问到a变量,然后改变a的值;
sizeof(求大小),举例说明:

sizeof可以测变量的大小,类型的大小,数组的大小,由于其是 *** 作符,所以括号可以省略,但当测类型的大小时,括号不可以省略,如上图所示。当sizeof测量对象是数组名时,数组名代表整个数组,这里延伸一下,除了sizeof(数组名),&(数组名)这两种情况(这两种情况数组名代表整个数组)外,其余情况数组名就是数组首元素的地址,且步距为元素类型的大小
~(按位取反)这个很好理解,就是将整数补码的二进制位按位取反;
–,++分为前置- -,++和后置- - ,++。例如:a++,++a这两者的区别在于是先使用a还是先执行a=a+1;前置就是先使用a,再++,后置就是先++,在使用a;当然如果一条语句只有a++,或者++a这种情况,两者使用效果相同,举个例子:

int main()
{
	int a = 1;
	if (a++)
		printf("a");
	if (++a)
		printf("b");
	return 0;
}

if(a++)就是先执行 if(a),然后a=a+1;if(++a)就是先执行a=a+1 ,然后if(a)。
(类型)强制类型转换,就是将变量强制转化为括号内的类型。例如:

int main()
{
	float a = 3.64f;
	int b = (int)a;
	return 0;
}

b就是将单精度浮点数a强制转化为int类型,这个时候是向下取整,变量b中存放3。

6.关系 *** 作符

关系 *** 作符分为:>,>=,<,<=,==,!=。前四种与数学中的关系比较使用方法一致,后两种是等于和不等于判断,注意与赋值操作符区分。

7.逻辑 *** 作符

逻辑 *** 作符分为两种,&&(逻辑与),||(逻辑或)。
&&(逻辑与),例如:

if((a+b)&&(b-c)&&(c*d)&&(d/f))
	printf("xxx");

当四个表达式全部为真时,打印xxx;当从左到右依次计算表达式值时,只要遇到表达式结果为假,后面的表达式就不会再计算了,判断结果就为假
||(逻辑或),例如:

if((a+b)||(b-c)||(c*d)||(d/f))
	printf("xxx");

当四个表达式全部为假时,就不打印xxx;当从左到右依次计算表达式值时,只要遇到表达式结果为真,后面的表达式就不会再计算了,判断结果就为真

8.条件 *** 作符

形如(a>b?a:b)这种形式的表达式即为条件 *** 作符又叫三目 *** 作符,表达式的意思为如果a>b为真,表达式结果就是a的值,否则就是b的值。

9.逗号表达式

形如(exp1,exp2,exp3,exp4,exp5)的表达式就是逗号表达式,逗号表达式从左到右依次计算,其结果为最后一个表达式的计算结果。

10.下标引用、函数调用和结构成员

下标引用 *** 作符[],形如有一个int arr[10],arr[3]中arr为数组名,[10]为索引值,代表访问第4个元素,[]的两个 *** 作数为arr和3,该 *** 作符满足交换律,即arr[3]和3[arr]是等价的,这两条语句可以转化为*(arr+3)或者*(3+arr),而这两条语句是相等的,故而说arr[3]和3[arr]是等价的。由此可以延伸出arr[3]的另一种理解,即从首地址开始,跳过3个元素,访问第4个元素。
函数调用 *** 作符(),例如:

int main()
{
	int a = 0;
	int b = 0;
	int c = Add(a, b);
	return 0;
}

Add(a,b)叫做函数调用,()叫做函数调用 *** 作符, *** 作数为:Add和a,b,即函数名和所有传递的参数,因此函数调用 *** 作符的 *** 作数至少为1个。函数调用 *** 作符这个()是不可以省略的
结构成员 *** 作符,分为点.和箭头->。举个栗子:

struct stu
{
	char name[20];
	char ID[20];
	char sex[5];
	int age;
};
int main()
{
	struct stu a = { "小明","1701","男",22 };
	struct stu* pa = &a;
	printf("%s %s %s %d\n", a.name, a.ID, a.sex, a.age);
	printf("%s %s %s %d\n", pa->name, pa->ID, pa->sex, pa->age);
	return 0;
}

可以发现点 *** 作符左边是结构体变量名,右边是成员变量名;
箭头 *** 作符左边是结构体变量指针,右边是成员变量名

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/921855.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存