评论

收藏

[C++] c语言_Day20_07_21

编程语言 编程语言 发布于:2021-07-21 21:23 | 阅读数:333 | 评论:0

c语言_Day20_07_21
1、操作符
1、位操作符
&按位与  |按位或    ^按位异或
位操作符的对象为内存中存储的二进制补码
与找,或找;异或相同为0,不同为1
int main()
{
int a = 1;
int b = -1;
printf("%d\n", a & b);  // 1
printf("%d\n", a | b);  // -1
printf("%d\n", a ^ b);  // -2
return 0;
}
面试题:

  • 不创建临时变量实现两数的交换
思路:1. 加减法(可能会溢出)
​           2. 异或法
// 加减法
int main()
{ 
int a = 10;
int b = 20;
a += b;
b = a - b;
a = a - b;
printf("a = %d b = %d\n", a, b);
return 0;
}
// 异或法
int main()
{
int a = 3;
int b = 5;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d\n", a);
printf("%d\n", b);
return 0;
}

  • 求一个整数存储在内存中的1的个数
思路:按位与。一个位与1进行按位与后,若该位为1则结果与1相同,反之则相反。对32个位遍历,重复进行上述操作,并且每次循环都对1进行左移操作,可判断32个位的1的个数
int main()
{
int num = -1;
int count = 0;
int move = 1;
for (int i = 0; i < 32; i++)
 {
    if ((num &amp; move) == move)
    {
      count++;
    }
    move = move &lt;&lt; 1;
  }
  printf("%d\n", count);
return 0;
}2、赋值操作符
赋值操作符可将右值赋予至左值
连续赋值:c语言支持连续赋值,但并不推荐
复合赋值:
+=    -=  =  /=  %=
\>>=  <<=
&=    |=  ^=
左值与右值进行算术操作,得到的结果赋值给左值
3、单目操作符
++    --
! ~
+    -
&

sizeof
(强制类型转换)
只有1个操作数的操作符
!:逻辑取反
&:取地址
*:解引用
sizeof:计算变量或数据类型所占用的内存大小
int main()
{
short s = 0;
int a = 10;
printf("%d\n", sizeof(s = a + 5));
printf("%d\n", s);
return 0;
}
sizeof中的表达式不会真实进行计算,故s并未被新赋值
~:按位取反
例:对11进行二进制操作,使其变为15(即二进制第3位由0变为1),再变为11
int main()
{
int a = 11;
a |= (1 << 2);
printf("%d\n", a);
a &= (~(1 << 2));
printf("%d\n", a);
return 0;
}
练习:
void test1(int arr[])
{
printf("%d\n", sizeof(arr));  // 4
printf("%d\n", sizeof(arr[0])); // 4
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch)); // 4
printf("%d\n", sizeof(ch[0]));  // 1
}
int main()
{
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("%d\n", sizeof(arr));  // 40
printf("%d\n", sizeof(ch)); // 10
test1(arr);
test2(ch);
return 0;
}
test函数接收数组的第一个元素的指针,故其大小在32位系统下为4个字节
4、关系操作符
\>    <   >=  <=  !=  ==
5、逻辑操作符
&&    ||
短路逻辑:对于逻辑与,若前项为假则不执行后面逻辑;对于逻辑或,若前项为真则不执行后面逻辑
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;  // 短路逻辑
printf("%d %d %d %d\n", a, b, c, d);
return 0;
}
6、条件操作符
exp1 ? exp2 : exp3
exp1为真,则返回exp2,反之返回exp3
7、逗号表达式
exp1, exp2, exp3...
用逗号隔开的多个表达式,从左向右依次执行,整个表达式结果为最后一个表达式
8、下标引用、函数调用和结构成员
[]
()
. ->
下标引用操作符用于访问数组元素
函数调用操作符用于调用函数
结构成员调用操作符用于调用结构体的成员:

  • '.'操作符用于调用结构体对象的成员
  • '->'操作符用于调用结构体对象的指针所指向的成员
struct Car
{
int speed;
char name[20];
};
int main()
{
struct Car car = { 60, "X1" };
printf("speed = %d  name = %s\n", car.speed, car.name);
printf("speed = %d  name = %s\n", (&car)->speed, (&car)->name);
return 0;
}
2、表达式求值
表达式求值需要注意两部分内容:优先级顺序类型转换
1、类型转换

  • 隐式类型转换
整形提升:表达式中的字符和短整形操作数在使用之前被转换为普通整形
int main()
{
char a = 3;
char b = 127;
char c = a + b;
printf("%d", c);
return 0;
}

  • 当用a(b)存放3(127)时,a(b)的空间大小为1byte,而3(127)的数据大小为4byte,故数据需要发生截断
  • 字符相加需进行整形提升(按数据类型的符号位进行提升),再计算
  • 将计算结果存放至c中,c的空间大小位1byte,而结果为整形,故数据需要截断
  • 打印整形,故c发生整形提升,得到补码,再转至原码打印
整型提升补充数据规则:

  • 正数补零
  • 负数补一
  • 无符号数补零

关注下面的标签,发现更多相似文章