C语言简易操作符

此篇操作符只涉及一些容易犯错的问题

1./(除)

想将除数结果为浮点数。

①可将被除数或者除数变成浮点数,也可以两者都加

②如果想在后面加f,那么前面一定是个浮点数,否则编译时会出现问题

int main() {
	float a = 6 / 5;//本质还是整数相除得整数
	printf("%f\n",a);// 1 
	float b = 6.0 / 5.0;
	printf("%f", b);// 1.2
	return 0;
}

2.移位运算符

        以负数为例,其实只要知道怎么移,负数的补码如何转化为原码,问题就不大了

1)左移运算符<<(注意开口方向)

int main() {
	int a = -7;
	//左移
	int b = a << 1;
	printf("%d",b); // -14
	return 0;
}

2)右移运算符>>

①算术右移:右边丢弃,左边补符号位(编译器一般来说,运算的是这种)

②逻辑右移:右边丢弃,左边补0

int main() {
	int a = -9;
	//右移
	int b = a >> 1;
	printf("%d",b); //-5
	return 0;
}

注意: a的值是没有变的!

计算n二进制的补码有多少个1

判断n是否为2次方的数字

//计算n二进制的补码有多少个1
int countnum1(int n ) {
	int i = 0;
	int count = 0;
	for ( i = 0; i < 32; i++)
	{
		if (((n >> i) & 1) == 1) {
			count++;
		}
	}
	return count;
}
//另解
int countnum1(int n ) {
	int count = 0;
	while(n){
        if(n % == 1){
            count++;
        }
        n /= 2;
    }
	return count;
}
//判断n是否为2^x次方的数字
//其实2^x的数字,其中只有一个1
// k & (k-1) == 0
int is2cifang(int k) {
	int i = 0;

		if ((k & (k - 1)) == 0)
		{
			return 1;
		}
		else
		{
			return -1;
		}
}
int main() {
	int a = 0;
	scanf("%d",&a);
	
	if (is2cifang(a) == 1)
	{
		printf("是2次方的数\n");
	}
	else
	{
		printf("不是2次方的数\n");
	}
	
	printf("%d", countnum1(a));
	return 0;
}

3)异或

计算两个数的二进制不同位的个数有多少个

int countnum1(int n) {
	int count = 0;
	int i = 0;
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	return count;
}

int main() {
	int a = 0;
	int b = 0;
	scanf("%d %d",&a,&b);
	int ret = a ^ b;
	int count = countnum1(ret);
	printf("%d",count);
	return 0;
}

 3.按位取反(要跟左移右移区分好)

        附上链接,按位取反是有式子可以记的,看👇

        通俗易懂-按位取反、原码反码补码间的转化_LimpidClear的博客-CSDN博客

4. sizeof

        sizeof的写法有以下几种

int main() {
	int a = -9;
	printf("%d",sizeof(a));
	printf("%d", sizeof(int));
	printf("%d", sizeof a );//由此也可证明它不是函数
	//sizeof是操作符,不是函数
	//printf("%d", sizeof int);不允许这样写
	return 0;
}

注意:sizeof()括号里的表达式是不参与运算的

int main() {
	short s = 5;
	int a = 6;
	printf("%d\n", sizeof(s = a + 2));//以s的字节数为准
	//因为跟int类型加一块,short类型还是不能变大,就像你还是你自己
	printf("%d", s);// s是值依旧不变,还是5
	return 0;
}

        注意:sizeof里面传进来的数组参数,本质上是数组的首地址,无论你是short还是其他什么类型,输出的只会是4(32位系统)或8(64位系统),因为地址占用内存的四或八个字节。

void test(int arr[]) {//本质传的是int *arr
    //即使上面的[]里面加了10,输出也是地址的内存大小
	printf("%d\n", sizeof(arr));
}
void test1(short ch[]) {//本质传的是int *arr
	printf("%d\n", sizeof(ch));
}
int main() {
	int arr[10] = { 0 };
	char ch[10] = { 0 };
	//这下面传进来的不是数组!
	printf("%d\n",sizeof(arr));//int类型4个字节*10 40 
	printf("%d\n", sizeof(ch));//short类型1个字节*10 10
	test(arr);//因为我的编译器是x86 这两个所以输出都是4
	test1(ch);//如果编译器是x64,这两个输出的是8
}

        sizeof当中的整型提升 

int main() {
	char c = 1;
	printf("%u\n",sizeof(c));// 1 %u 表示按unsigned int格式输入或输出数据
    //全部用%d,结果也一致
	printf("%u\n", sizeof(+c));// 4
	printf("%u\n", sizeof(-c));// 4
	printf("%u\n", sizeof(!c));//这个也是4,但vscode是1,按gcc的来,就是4
	return 0;
}

5.前置++跟后置++

        这个不过多赘述

        前置++:先加加,后使用,跟大家平常想的是一样的

        b = a++;

        后置++:先使用,后加加。也就是你先用a的时候,它还是它本身的数,你用b的时候,才会加1,如有问题,请指正。

        在这里,我想强调的是,面对式子很多个前置++,后置++进行加减运算时,其实这个很“鸡肋”,因为你在Linux系统编译器上跟windows的编译器上,有时候会发生不一致的结果。所以尽量不要用这种进行复合运算。

        再讲一下&&跟||还有前后置++的结合

//++与&&
int main() {
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	//先使用a,那么a是0,那么程序已经判断为false,后面就不会执行了,但是a还是要++的
	printf("a = %d\nb = %d\nc = %d\nd = %d\n ",a,b,c,d); // 1 2 3 4
	printf("%d",i);// 0
	return 0;
}
int main() {
	int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	//为了验证是否都为1,都会执行
	printf("a = %d\nb = %d\nc = %d\nd = %d\n ",a,b,c,d); // 2 3 3 5
	printf("%d",i);// 1
	return 0;
}
//++与||
int main() {
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ || ++b || d++;
	//a使用时为0,判断b为2,true,后面就不执行了
	printf("a = %d\nb = %d\nc = %d\nd = %d\n ",a,b,c,d); // 1 3 3 4
	printf("%d",i);// 1
	return 0;
}

 习题:

int main() {
	int a, b, c;
	a = 5;
	c = ++a;// c = 6;a = 6
	b = ++c, c++, ++a, a++;//c = 8;a = 8; b = 7;
	b += a++ + c;//先使用a,让a+c = 16 再加b b= 23; a = 9;
	printf("a = %d b = %d c = %d\n",a,b,c);// 9 23 8
	return 0;
}

6.取地址&与按位与&区别

        按位与:全一才为1,其余情况全为0

7.==与=区别

        ==数字比较是否相等

        而字符串不能用==,用函数strcmp(),strcmp()函数详见👇

      C语言简单函数跟递归_LimpidClear的博客-CSDN博客

        =赋值

8.逻辑与或,按位与或

        逻辑与&&

        按位与&

        逻辑或||

        按位或|

        逻辑运算就只是判断是否位真假,按位运算

        按位或:全0才为0,其余全为1

9.三目运算符

        判断式?真实现的代码:假实现的代码

10.逗号表达式

        要从做向右依次计算,但是整个表达式的结果是最后一个表达式的结果

	int a = 1;
	int b = 2;
	int c = 3;
	int d = (a = b + 2,c = a -4,b = c+2);
	printf("%d\n", d);// 2 
	printf("%d\n", a);// 4
	printf("%d\n", c);// 0

int main() {
	//方法都没写,只是一个示例
	int a = get_value();
	count_value(a);
	while (a >0)
	{
		int a = get_value();
		count_value(a);
	}
	//其实等价于
	int a = 0;
	while (a = get_value(),count_value(a),a > 0)
	{

	}
	return 0;
}

         sizeof跟逗号表达式的结合

int main() {
	int arr[] = {1,2,3,(3,4)};//其实就是{1,2,3,4}
	printf("%d",sizeof(arr));// 4*4 = 16
	return 0;
}

11.访问一个结构的成员

        .        结构体.成员名

        ->      结构体指针->成员名   

struct Book
{
	char name[10];
	int price;
};
int main() {
	struct Book b = {"C",20};//这个struct要加
	//结构体变量名.成员名
	printf("%s ",b.name);
	printf("%d\n", b.price);
	//结构体指针->成员名   
	struct Book* pa = &b;
	printf("%s ", pa->name);
	printf("%d\n", pa->price);
	//用*pa.成员名也行
	return 0;
}

12.[]下标引用

        下标引用要注意数组越界的问题,例如int[10];

        就不可能有int[10] = 2;因为只有0-9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值