C语言——操作符详解2

目录

  • 0.过渡
    • [0.1 不创建临时变量,交换两数](#0.1 不创建临时变量,交换两数)
    • [0.2 求整数转成二进制后1的总数](#0.2 求整数转成二进制后1的总数)
  • 1.单目表达式
  • [2. 逗号表达式](#2. 逗号表达式)
  • [3. 下标访问[ ]、函数调用( )](#3. 下标访问[ ]、函数调用( ))
    • [3.1 下标访问[ ]](#3.1 下标访问[ ])
    • [3.2 函数调用( )](#3.2 函数调用( ))
  • [4. 结构体成员访问操作符](#4. 结构体成员访问操作符)
    • [4.1 结构体](#4.1 结构体)
      • [4.1.1 结构体的申明](#4.1.1 结构体的申明)
      • [4.1.2 结构体变量的定义和初始化](#4.1.2 结构体变量的定义和初始化)
    • [4.2 结构体成员的访问](#4.2 结构体成员的访问)
      • [4.2.1 结构体成员的直接访问](#4.2.1 结构体成员的直接访问)
      • [4.2.2 结构体成员的间接访问](#4.2.2 结构体成员的间接访问)
  • [5. 操作符的属性:优先级、结合性](#5. 操作符的属性:优先级、结合性)

0.过渡

  • 在操作符1中我们最后讲了位操作符的概念
  • 这里我想举几个例子加深理解

0.1 不创建临时变量,交换两数

  • 这是一道很变态的面试题
  • 首先我们可以看看下面两个等式:
  1. a ^ a =0
  2. a ^ 0 = a
  • 接着我们来理解一下这道变态面试题的答案
c 复制代码
#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	a = a^b;
	b = a^b;//根据上面的代码,这里的a^b=a^b^b=a^0=a,这里相当于把a给b
	a = a^b;//根据上面的代码,这里的a^b=a^a^b=0^b=b,这里相当于把b给a
	printf("a = %d b = %d\n", a, b);
	return 0;
}
  • 运行结果如下:

0.2 求整数转成二进制后1的总数

  • 首先我们看一下当一个二进制数和1按位与后的结果
  • 我们发现当一个二进制的最后一位是 0 时,和1按位与后的结果为0
  • 当最后一位为1时,按位与1后的结果时1
  • 这样就相当于把二进制的最后一位给取出来了,那么我只要加个循环,把每一位都取出来再相加即可(这里我为了方便只写了八个二进制数,×86环境为32位,×64环境为64位)
  • 所以代码如下:
c 复制代码
#include <stdio.h>

int main()
{
	int num = -1;
	int i = 0;
	int count = 0;//计数
	
	for(i=0; i<32; i++)
	{
		if( num & (1 << i) )
		count++;
	}
	
	printf("⼆进制中1的个数 = %d\n",count);
	
	return 0;
}
  • 但是这样有一个缺点,就是不管二进制是多少都要循环32遍,如果二进制只是1,那31遍循环都白循环了
  • 所以我们想想是否还有更加高效的代码呢
  • 比如我们可以试试 num&(num-1)
  • 我们会发现最后的1消失了
  • 同理,如果我们把结果再重复一次运算
  • 我们会发现倒数第二个1也消失了,如果我们再重复一次会不会倒数第四位的1也消失呢?
  • 我们发现确实如此!
  • 那么我们只要再加上num != 0 这个条件就可以循环起来了
  • 代码如下:
c 复制代码
#include <stdio.h>

int main()
{
	int num = -1;
	int i = 0;
	int count = 0;//计数
	
	while(num)
	{
		count++;
		num = num & (num-1);
	}
	
	printf("⼆进制中1的个数 = %d\n",count);
	
	return 0;
}

1.单目表达式

  • 单目操作符有这些:
  • !、++、--、&、*、+、-、~ 、sizeof、(类型)

2. 逗号表达式

  • 顾名思义,就是一些表达式用逗号连接起来,如图:
  • 逗号表达式,从左向右依次执行。整个表达式的结果是最后⼀个表达式的结果。

3. 下标访问[ ]、函数调用( )

3.1 下标访问[ ]

  • 操作数:⼀个数组名 + ⼀个索引值

3.2 函数调用( )

  • 接受⼀个或者多个操作数:第⼀个操作数是函数名,剩余的操作数就是传递给函数的参数。
c 复制代码
#include <stdio.h>

void test1()
{
	printf("hehe\n");
}

void test2(const char *str)
{
	printf("%s\n", str);
}

int main()
{
	test1(); //这⾥的()就是作为函数调⽤操作符。
	test2("hello bit.");//这⾥的()就是函数调⽤操作符。
	
	return 0;
}

4. 结构体成员访问操作符

4.1 结构体

  • C语⾔已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的,
  • 假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不行的。描述⼀个学生需要名字、年龄、学号、身高、体重等;描述⼀本书需要作者、出版社、定价等。
  • C语言为了解决这个问题,增加了结构体这种自定义的数据类型,让程序员可以自己创造适合的类型。
  • 结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:标量、数组、指针,甚⾄是其他结构体

4.1.1 结构体的申明

  • 比如描述一个学生:
c 复制代码
struct Stu
{
	char name[20];//名字
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
}a;//分号不能丢,这里的a为结构体类型的全局变量

4.1.2 结构体变量的定义和初始化

c 复制代码
//变量的定义
struct Point
{
	int x;
	int y;
}p1; //声明类型的同时定义变量p1

struct Point p2; //定义结构体变量p2
struct Point p3 = {10, 20};//初始化

struct Stu //类型声明
{
	char name[15];//名字
	int age; //年龄
};

struct Stu s1 = {"zhangsan", 20};//初始化
struct Stu s2 = {.age=20, .name="lisi"};//指定顺序初始化

//嵌套结构
struct Node
{
	int data;
	struct Point p;
	struct Node* next;
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化

struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

4.2 结构体成员的访问

4.2.1 结构体成员的直接访问

  • 结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。如下所示:
c 复制代码
#include <stdio.h>

struct Point
{
	int x;
	int y;
}p = {1,2};

int main()
{
	printf("x: %d y: %d\n", p.x, p.y);
	return 0;
}
  • 使用方式:结构体变量 . 成员名

4.2.2 结构体成员的间接访问

  • 有时候我们得到的不是⼀个结构体变量,而是得到了⼀个指向结构体的指针。如下所示:
c 复制代码
#include <stdio.h>

struct Point
{
	int x;
	int y;
};

int main()
{
	struct Point p = {3, 4};
	struct Point* ptr = &p;
	ptr->x = 10;
	ptr->y = 20;
	printf("x = %d y = %d\n", ptr->x, ptr->y);
	return 0;
}
  • 使用方式:结构体指针 -> 成员名

5. 操作符的属性:优先级、结合性

  • 链接在这里------操作符优先级
  • 结合性是指在遇到相同优先级的操作符的时候的运算顺序

最后,

恭喜你又遥遥领先了别人!

相关推荐
杨荧26 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
白子寰33 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
王俊山IT1 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。1 小时前
c++多线程
java·开发语言
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
神奇夜光杯1 小时前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue1 小时前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧1 小时前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端