C语言初阶--操作符详解(下)

简介: C语言初阶--操作符详解(下)

5.单目操作符

单目操作符介绍

!           逻辑反操作

-           负值

+           正值

&           取地址

sizeof      操作数的类型长度(以字节为单位)

~           对一个数的二进制按位取反

--          前置、后置--

++          前置、后置++

*           间接访问操作符(解引用操作符)

(类型)       强制类型转换


5.1 !操作符实例

#include<stdio.h>

int main()

{

   //C语言中0表示假,非0表示真

   int flag = 5;

   if (flag)

   {

       printf("haha\n");

   }

   if (!flag)

   {

       printf("hehe\n");

   }

   printf("%d\n", !flag);

   printf("%d\n",flag);

   return 0;

}


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


5.2 _Bool类型

这里提一下布尔类型,没必要赋值浮点数,负数等待,布尔类型就是为了不让胡乱赋值造的。

//布尔类型是用来表示真假的类型

#include<stdio.h>

#include<stdbool.h>

int main()

{

   _Bool flag = true;//true,false

   if (flag)

   {

       printf("hehe\n");

   }

   else

   {

       printf("hahaha\n");

   }

}


5.3 ++、--操作符

++a//先++,后使用

a++//先使用,后++

--//相同道理


5.4 ()强制转换操作符

int main()

{

 int a= (int)3.14;//强制类型转换,只拿整数部分,小数不要了

   printf("%d", a);

}


//少用

int main()

{

   srand((unsigned int)time());//需要一个time函数的返回值作为参数,但time()函数的返回值是time_t,srand又需要unsigned int类型。

}


5.5 unsigned int 问题:

int main()
{
  unsigned int   num = -10;
  printf("%u\n", num);
   int num1 = -10;
     printf("%d\n", num1);
  return 0;
}


f3916cf14134471da621e5d3a9064acd.png

理解: unsigned int无符号位将本来数据的最高位符号位变成了有效位,那么数据就变大了。


5.6 &、*操作符

int main()

{

   int a = 10;

  printf("%p\n", &a);

   int* pa = &a;

 

   char ch = 'w';

   char* pc = &ch;

   //printf("%p\n", &ch);

   char arr[10] = { 0 };

   char* p2 = arr;

   char* p3 = &arr[0];

   char* p = "abcdef";

   printf("%p\n", p);

   printf("%c\n", *p);//打印的是a

   return 0;

}

void test1(int *arr, int sz)
{
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    printf("%d ", arr[i]);//*(arr+i),arr是首元素地址+i跳过i个整型
  }
}
int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  test1(arr, sz);
  return 0;
}

从int*pa=&a来看,pa是指针变量,类型是int*,&a是取出a在内存空间中开辟的地址,*是解引用操作符,通过a的地址找到a,可以改变a的值。

而arr是首元素地址,+i跳过i个整型。


5.7 sizeof

函数调用的时候,要写()但是sizeof后边的括号可以省略,说明sizeof不是函数

sizeof既是操作符,也是关键字,可以求变量(类型)所占空间的大小

#include<stdio.h>
int main(){
int a = 10;
  short s = 5;
  printf("%d\n", sizeof(s = a + 3));
  printf("%d\n", s);
  return 0;
}

d2eba7844a1e4adf80e241a869f78a2a.png

上图说明sizeof内部的表达式是不计算的。

#include<stdio.h>
int main()
{
  int a = 10;
  printf("%d\n", sizeof(a));
  printf("%d\n", sizeof a);//ok
  printf("%d\n", sizeof(int));//但是不能写出sizeof int
  int arr[10] = {0};
  printf("%d\n", sizeof arr);//ok
  printf("%d\n", sizeof(arr));//ok
  printf("%d\n", sizeof(int[10]));//ok
  return 0;
}


c408b1811f74459bbbf828b9acf1f9cb.png

注意:不可写成sizeof 类型 ,不加()是不行的


5.8 sizeof与数组

#include<stdio.h>
void test1(int arr[])//数组传参,形参可以写成数组,也可以写出指针
{               //即使写成数组,本质上也是指针
  printf("%zd\n", sizeof(arr));
}
void test2(char ch[])
{
  printf("%zd\n", sizeof(ch));
}
int main()
{
  int arr[10] = { 0 };
  char ch[10] = { 0 };
  printf("%zd\n", sizeof(arr));//计算的数组大小
  printf("%zd\n", sizeof(ch));//计算的数组大小
  test1(arr);
  test2(ch);
  return 0;
}


4fd1064796ba42d68b6a6cf944eff549.png


5.9 ~按位取反操作符:

~按位取反

00000000000000000000000000000000

11111111111111111111111111111111 - 补码是全1

int main()
{
  int a = 0;
  printf("%d\n", ~a);//?
  return 0;
}

999749fcf69e47aea782e58cdb0c0170.png

#include<stdio.h>
int main()
{
  int a = 9;
  //00000000000000000000000000001001
  //00000000000000000000000000010000      1<<4
  //00000000000000000000000000011001
  //
  //把a的二进制中第5位改成1
  a |= (1<<4);
  printf("%d\n", a);
  //把a的二进制中的第5位改回来,变成0
  //00000000000000000000000000011001
  //11111111111111111111111111101111
  //00000000000000000000000000001001
  a &= (~(1 << 4));
  printf("%d\n", a);//9
  return 0;
}


6.关系操作符

>

>=

<

<=

!=   用于测试“不相等”

==      用于测试“相等”


7.逻辑操作符

&&     逻辑与

||        逻辑或


&(按位与)和|(按位或)是针对2进制来说的,而上述两个是针对真假来说的。

1&2----->0

1&&2---->1

1|2----->3

1||2---->1


&&逻辑与

//短路
int main()
{
  int i = 0, a = 0, b = 2,c=3, d = 4;
  i = a++ && ++b && d++;
  printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
  return 0;
}

2892edab8fa448cdbaa200f946dc8a33.png

&&左边为假,右边无需计算(自左向右, 只要有一个操作数为假,后面不用算了)。

dc26e60c4e48411eb34eedc6cc21db29.png

||        逻辑或

int main()
{
  int i = 0, a =0, b = 2, c = 3, d = 4;
  i = a++ || ++b || d++;
  printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
  return 0;
}

fd261501011840aba588be1f7b396fef.png

|| 左边为真,右边无需计算(自左向右, 只要有一个操作数为真,后面不用算了)。

fbb4a25d787f4ff9b9709e16b2a17dd2.png

8.条件操作符

exp1 ? exp2 : exp3

真返回条件2,假返回条件3

#include<stdio.h>
int main()
{
  int a = 10;
  int b = 20;
  int m = 0;
  m= (a > b ? a : b);
  printf("%d\n", m);
  b = (a > 5 ? 3 : -3);
  printf("%d\n", b);
  return 0;
}

a0e18ba1670f4333855a65d77df9761f.png


9.逗号表达式

逗号表达式,就是用逗号隔开的多个表达式。

逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。

int main()
{
  int a = 1;
  int b = 2;
  int c = (a > b, a = b + 10, a, b = a + 1);//逗号表达式,返回最后一个值,但前面的会影响后面的变量
  printf("%d", c);
}

beb4dab8d27d47a6a8f2bf0a5181dfb3.png

逗号表达式,返回最后一个值,但前面的会影响后面的变量


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

1. [ ] 下标引用操作符 ,操作数:一个数组名 + 一个索引值

2. ( ) 函数调用操作符 接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

int main()

{

   int arr[10] = { 1,2,3,4,5,6 };

   printf("%d\n", arr[4]);//下标引用操作符,操作数是arr,10;

 

   int len = strlen("abcdef");//函数调用操作符,操作数是strlen,"abcdef"

   return 0;

}

3. 访问一个结构的成员

.       结构体.成员名

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


结构体-自定义类型(聚合类型),把简单的类型集合在一起

生活中有些对象要被描述的话,不能简单的使用单个内置类型(char int short long 、 long long 、 float、 double)

例如:

书:书名,作者,出版社,定价

学生:名字,年龄,学号.....

struct Book
{
  char name[20];
  char author[30];
  int price;
};
void print1(struct Book *b)
{
  printf("《%s》%s %d\n", b->name, b->author, b->price);
  printf("《%s》%s %d\n", (*b).name, (*b).author, (*b).price);
}
int main()
{
  struct Book b1 = { "单人破b","niko",60 };
  struct Book b2 = { "全体白给","simple",80 };
  //结构体变量.成员名
  printf("《%s》 %s %d\n", b1.name, b1.author, b1.price);
  printf("《%s》 %s %d\n", b2.name, b2.author, b2.price);
  print1(&b1);
  //print1(&b1);
  return 0;
}

98803170bc234726a20abfcc57b0292e.png

#include<stdio.h>
struct Stu {
  char name[10];
  int age;
  char sex[5];
  double score;
};
void set_age1(struct Stu stu)
{
  stu.age = 18;
}
void set_age2(struct Stu *stu)
{
  stu->age = 18;
}
int main()
{
  struct Stu stu;
  struct Stu* pStu = &stu;
  stu.age = 20;
  set_age1(stu);
  printf("%d\n", stu.age);
  set_age2(&stu);
  printf("%d\n", stu.age);
  // set_age2(stu);
}

03e8a9de37254238948cfd6a463f9466.png

这是结构体指针,第一个是传值调用,第二个是传址调用。

相关文章
|
3月前
|
存储 C语言 索引
【C语言篇】操作符详解(下篇)
如果某个操作数的类型在上⾯这个列表中排名靠后,那么⾸先要转换为另外⼀个操作数的类型后执⾏运算。
72 0
|
3月前
|
程序员 编译器 C语言
【C语言篇】操作符详解(上篇)
这是合法表达式,不会报错,但是通常达不到想要的结果, 即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到右计算,所以实际执⾏的是下⾯的表达式。
238 0
|
15天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
30 10
|
1月前
|
存储 编译器 C语言
【C语言】简单介绍进制和操作符
【C语言】简单介绍进制和操作符
152 1
|
1月前
|
存储 编译器 C语言
初识C语言5——操作符详解
初识C语言5——操作符详解
163 0
|
3月前
|
C语言
C语言操作符(补充+面试)
C语言操作符(补充+面试)
45 6
|
3月前
|
存储 编译器 C语言
十一:《初学C语言》— 操作符详解(上)
【8月更文挑战第12天】本篇文章讲解了二进制与非二进制的转换;原码反码和补码;移位操作符及位操作符,并附上多个教学代码及代码练习示例
56 0
十一:《初学C语言》—  操作符详解(上)
|
4月前
|
C语言
五:《初学C语言》— 操作符
本篇文章主要讲解了关系操作符和逻辑操作符并附上了多个代码示例
43 1
五:《初学C语言》—  操作符
|
4月前
|
编译器 C语言
【C语言初阶】指针篇—下
【C语言初阶】指针篇—下
|
4月前
|
存储 C语言
【C语言初阶】指针篇—上
【C语言初阶】指针篇—上