Bootstrap

C语言知识点总结03

一、获取数据储存大小

   使用sizeof 可以获取数据类型或变量、字面量的存储大小,单位是字节。sizeof返回一个size_t类型的无符号整数值,格式占位符是 %zu

1.基本类型的大小

int main()

{

    // sizeof:可以检查出 类型 占得内存大小->字节

    printf("char=%zu\n", sizeof(char));

    printf("short=%zu\n", sizeof(short));

    printf("int=%zu\n", sizeof(int));

    printf("long=%zu\n", sizeof(long));

    printf("long long=%zu\n", sizeof(long long));

    printf("float=%zu\n", sizeof(float));

    printf("double=%zu\n", sizeof(double));

    printf("long double=%zu\n", sizeof(long double));

    return 0 ;

}

 2.变量所占内存大小

int main()

{

// sizeof:可以检查出 变量 占得内存大小->字节

    char ch = 'a';

    int a = 12306;

    double num = 3.14;

    printf("a=%zu\n", sizeof(a));

    // 检测对应变量的时候,小括号可以省略

    printf("ch=%zu\n", sizeof ch);

    printf("num=%zu\n", sizeof num);

     return 0;

}

 

3.检测字面量和字符的大小

   // 检测字面量

    // 字符本质即为整数=97->默认int类型

  //6.6是小数默认为double类型

    printf("字符a=%zu\n", sizeof 'a');

    printf("小数6.6=%zu\n", sizeof 6.6);

 

二、类型自动转换

1.自动类型转换

(1)不同类型整数进行运算,窄类型整数自动转换为宽类型整数。

(2)不同类型浮点数进行运算,精度小的类型自动转换为精度大的类型。

(3)整数与浮点数进行运算,整数自动转换为浮点数。

int main()
{
    //整数:short int long long
    short a = 12;
    int b = 88;
    printf("%d\n", a + b);
    printf("a+b=%zu\n", sizeof(a + b));
    int num = 99;
    long num1 = 23;
    printf("%ld\n", num + num1);
    printf("num+num1=%zu\n",sizeof(num + num1));

    //浮点数:float  double  long double
     float a = 8.8;
     double b = 9.9;
     printf("小数a+b=%lf\n",a + b);
     printf("所占内存大小=%zu\n",sizeof(a + b));

    //整数与小数运算符
    int a = 110;
    double b = 6.68;
    printf("a+b=%.2lf\n",a + b);
    printf("a+b=%zu\n",sizeof(a + b));

    //有符号与无符号计算->无符号的!!!
    int a = -100;
    unsigned int b = 98;
    printf("%u", a + b);

    return 0;
}

2.强制类型转换

    自动类型转换(隐式类型转换)中的宽类型赋值给窄类型,编译器是会产生警告的,提示程序存在潜在的隐患,如果非常明确地希望转换数据类型,就需要用到强制(或显式)类型转换。

#include <stdio.h>

int main()
{
    // 类型->double类型小数
    double a = 3.6;
    double b = 8.88721;
    //(int)a:把double类型强转换为int类型进行计算
    int result = (int)a + (int)b;
    printf("%d\n", result);
    return 0;
}

提示:在变量前面加上(转变类型)不然无法转换会报错

三、运算符

 运算符是一种特殊的符号,用以用于数据的运算、赋值和比较等。按照操作数个数分类分为:一元运算符(一目运算符)二元运算符(二目运算符)三元运算符(三目运算符)。按照功能分类算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符。

1.算数运算符

运算符

描述

操作数个数

组成的表达式的值

副作用

+

正号

1

操作数本身

-

负号

1

操作数符号取反

+

加号

2

两个操作数之和

-

减号

2

两个操作数之差

*

乘号

2

两个操作数之积

/

除号

2

两个操作数之商

%

取模(取余)

2

两个操作数相除的余数

++

自增

1

操作数自增前或自增后的值

- -

自减

1

操作数自减前或自减后的值

#include <stdio.h>

int main()
{
    // + -:正负符号
    // int a = 19;
    // int b = -123;
    // printf("%d %d\n", a, b);

    //+ - * / %
    int a = 10;
    int b = 4;
    printf("a+b=%d\n", a + b);
    printf("a-b=%d\n", a - b);
    printf("a*b=%d\n", a * b);
    // 整数相除小数部分没了!!!
    printf("a/b=%d\n", a / b);
    printf("a%b=%d\n", b % a);

    //这些数学运算对于变量ab没有影响的
    printf("a=%d\n",a);


  /**
  * 
  * ++ 自增
  * -- 自减
  * 这两个符号一般出现在变量前面或者后面 加上1或者减去1
  *
  * ++:如果出现在变量前面(++a),当前这一次操作,在使用之前就加上1了!!!
  * --:如果出现在变量前面(--a),当前这一次操作,在使用之前就减去1了!!!
  *
  * ++:如果出现在变量后面(a++),当前这一次操作,在使用之后就加上1了!!!
  * --:如果出现在变量后面(a--),当前这一次操作,在使用之后就减去1了!!!
  */
    int num = 9;
     // 使用变量进行操作
    printf("++num=%d\n", ++num); // 第二次10
    printf("num=%d\n", num);//第三次 10

     int a = 89;//第一次
     // 使用变量进行操作
     printf("a++=%d\n", a++);//第二次
     printf("a=%d\n",a);//第三次

     int c = 51;          // 第一次
     printf("%d\n", --c); // 第二次
     printf("%d\n",c);//第三次

     int d = 67;//第一次
     printf("d--=%d\n",d--);//第二次
     printf("d=%d\n",d);//第三次

    int num = 10;
    int result = num++ + 7;
    printf("result=%d\n", result);
    printf("%d\n",num);

    return 0;
}

自增自减运算符尤为重要,要根据代码自行一个一个尝试,理解前置和后置所表现出来的不同效果,为以后的控制循环语句提供准备。

 2.比较运算符及关系运算符

#include <stdio.h>

int main()
{
    // 比较运算符(6) == != > >= < <=
    //对于变量没有副作用
    //比较运算最终的结果:数字0(不成立)|数字1(成立)
    int a = 99;
    int b = 37;
    printf("a==b:结果%d\n", a == b);
    printf("a!=b:结果%d\n", a != b);
    printf("a>b:结果%d\n", a > b);
    printf("a>=b:结果%d\n", a >= b);
    printf("%d\n", 3 >= 3);
    printf("a<=b:结果%d\n", a <= b);
    printf("a<b:结果%d\n", a < b);


    // 逻辑运算符:&&->两个同时为真,才为真![串联图]
     int a = 99;
     int b = 55;
     printf("a&&b:结果%d\n", a && b);
     printf("数字1&&数字2:结果%d\n", 0 && b);
     printf("数字1&&数字2:结果%d\n", 12 && 0);
     printf("表达式1&&表达式2:结果%d\n", a > 10 && ++b);

    // 逻辑或:||->两者只要有一个为真,即为真【并联图】
     int num = 0;
     printf("数字1||数字2:结果%d\n", 3 || 0);
     printf("数字1||数字2:结果%d\n", ++num || 0);
     printf("表达式1||表达式2:结果%d\n", 3 > 8 || 100 > 99);

    // 逻辑非:!取反
     printf("%d\n", !0);
     printf("%d\n", !99);
     printf("%d\n", !!!67);

    // 练习
    int result = (3 > 8 && 3 < 9) || 0;
    printf("结果:%d\n", result);

    return 0;
}

3.赋值运算符

#include <stdio.h>

int main()

{

    // 赋值运算符: = += -= *= /= %=

    int a = 123;

    a += 6; // 相当于 a = a + 6   等于129

    a -= 8; // 相当于 a = a - 8   等于121

    a *= 2; // 相当于 a = a * 2   等于242

    a /= 3; // 相当于 a = a / 3   等于80

    a %= 3; // 相当于 a = a % 3   等于2

    printf("a=%d\n", a);

    return 0;

}

 4.位运算符

运算符

描述

操作数个数

副作用

&

按位与

2

|

按位或

2

^

按位异或

2

~

按位取反

1

<<

按位左移

2

>>

按位右移

2

注意:操作数进行位运算的时候,以它的补码形式进行运算。

0为假 1为真

&运算符

两个数字都要为1才能得到真,只要有一个是假就是0

 int a = 22;

     int b = -19;

             原码                反码        补码

     22   0001 0110   0001 0110   0001 0110

    -19   1001 0011   1110 1100   1110 1101

     ---------------------------------------

      4                            0000 0100

     

     printf("a & b = %d\n", a & b);/*因为数字都是在255以内所以只列了8位进行运算可以不止         是八位16位三十二位都可以看计算的数字大小*/

 | 运算符

有1即为真也就是说两个数字里面只要有一个1就是真的也就是得1。

 int a =22;
 int b =-19;
          原码        反码        补码
   22   0001 0110   0001 0110   0001 0110
  -19   1001 0011   1110 1100   1110 1101
    ---------------------------------------
   -1   1000 0001   1111 1110   1111 1111
  
     printf("a | b = %d\n", a | b);
     //往下运算符举例都是a=22 b=-19

^运算符

或与运算符是两个数字不同为真,相同为假

   22   0001 0110   0001 0110   0001 0110
  -19   1001 0011   1110 1100   1110 1101
   ---------------------------------------
  -5    1000 0101   1111 1010   1111 1011
   
   printf("a ^ b = %d\n", a ^ b);

 ~按位取反符

 /*      原码        反码        补码
      22   0001 0110   0001 0110   0001 0110
     -19   1001 0011   1110 1100   1110 1101
     ---------------------------------------
      ~a  1001 0111   1110 1000   1110 1001  -23
      ~b  0001 0010   0001 0010   0001 0010   5
 */
     printf("~a:结果位%d\n", ~a);
     printf("~a:结果位%d\n", ~b);

补码直接按位取反,如果取完反得到的是负数也就是符号位是1,记得计算出原码

>> <<按位左移、按位右移

正数按位左移和右移都是补0,负数右移时记得补的是1

 //-----------------左移动,右移动----------//
     /*      原码        反码        补码
     22   0001 0110   0001 0110   0001 0110
    -19   1001 0011   1110 1100   1110 1101    
     ---------------------------------------
     a<<2 0101 1000   0101 1000    0101 1000  88
     b<<2 1100 1100   1011 0011    1011 0100 -76
     a>>2 0000 0101   0000 0101    0000 0101  5
     b>>2 1000 0101   1111 1010    1111 1011 -5
     */
     printf("a<<2:结果为%d\n", a << 2);
     printf("b<<2:结果位%d\n", b << 2);
     printf("a>>2:结果位%d\n", a >> 2);
     printf("b>>2:结果位%d\n", b >> 2);
     return 0;

5.三元运算符

基本语法条件表达式? 表达式1: 表达式2;

如果条件表达式为非0(真),整个表达式的值是表达式;如果条件表达式为0(假),整个表达式的值是表达式2;

      int num = 6;
      int num1 = 9;
      printf("三元运算:结果%d\n", 1 ? num : num1);
      printf("三元运算:结果计算出谁大:%d\n", num > num1 ? num : num1);

6.运算符优先级

优先级

运算符

名称或含义

结合方向

1

[]

数组下标

左到右

()

圆括号

.

成员选择(对象)

->

成员选择(指针)

2

-

负号运算符

右到左

(类型)

强制类型转换

++

自增运算符

--

自减运算符

*

取值运算符

&

取地址运算符

!

逻辑非运算符

~

按位取反运算符

sizeof

长度运算符

3

/

左到右

*

%

余数(取模)

4

+

左到右

-

5

<<

左移

左到右

>>

右移

6

>

大于

左到右

>=

大于等于

<

小于

<=

小于等于

7

==

等于

左到右

!=

不等于

8

&

按位与

左到右

9

^

按位异或

左到右

10

|

按位或

左到右

11

&&

逻辑与

左到右

12

||

逻辑或

左到右

13

?:

条件运算符

右到左

14

=

赋值运算符

右到左

/=

除后赋值

*=

乘后赋值

%=

取模后赋值

+=

加后赋值

-=

减后赋值

<<=

左移后赋值

>>=

右移后赋值

&=

按位与后赋值

^=

按位异或后赋值

|=

按位或后赋值

15

,

逗号运算符

左到右

;