ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第五章-C语言操作符

2021-10-26 20:00:07  阅读:119  来源: 互联网

标签:include return int C语言 第五章 操作符 printf main


一、 操作符分类

(1)算术操作符

+(加)-(减) *(乘)   /(除)   %(取模)

#include<stdio.h>
int main()
{
    //  / 操作符
    int a = 5 / 2;//如果两个操作数都为整数,执行整数除法
    //商2余1
    double a2 = 5 / 2.0;//有浮点数执行的就是浮点数除法
    // %操作符
    int b = 5 % 2;//两个操作数必须为整数
    printf("a=%d\n", a);//a=2
    printf("a2=%lf\n", a2);//a=2.500000
    printf("b=%d\n", b);//b=1
    return 0;
}

(2) 移位操作符

 << 左移操作符

#include<stdio.h>
int main()
{
    int a = 16;//0000000010000,即2^4
    //>>--右移操作符
    //移动的是二进制
    //算术右移--右丢弃,左补原位符号(通常使用)
    //逻辑右移--右丢弃,左补0
    int b=a >> 1;//8--2^3
    printf("%d\n", b);
    return 0;
}
#include<stdio.h>
int main()
{
    int a = -1;
    //整数二进制表述:原码、反码、补码
    //存储在内存的是补码
    //原码100000000000000000000000001
    //反码111111111111111111111111110
    //补码111111111111111111111111111
    int b = a >> 1;
    printf("%d\n", b);//-1
    return 0;
}

 >> 右移操作符    

#include<stdio.h>
int main()
{
    int a =5;//101
    int b = a << 1;//1010=2^3+2=10
    //<<--左边丢弃,右边补零
    printf("%d\n", b);//10
    return 0;
}

注:

移位操作符的操作数只能是整数。

对于移位运算符,不要移动负数位,这个是标准未定义的

(3)位操作符

& 按位与

#include<stdio.h>
int main()
{
    //& 按二进制位与
    //两个为1,则为1
    //一个为0,则为0
    int a = 3;//011
    int b = 5;//101
    int c = a & b;//001
    printf("%d\n", c);
    return 0;
}

| 按位或

#include<stdio.h>
int main()
{
    //| 按二进制位或
    //两个为0,则为0
    //一个为1,则为1
    int a = 3;//011
    int b = 5;//101
    int c = a |b;//111
    printf("%d\n", c);//7
    return 0;
}

^ 按位异或

#include<stdio.h>
int main()
{
    //^ 按位异或
    //相异为1
    //相同为0
    int a = 3;//011
    int b = 5;//101
    int c = a^b;//110
    printf("%d\n", c);//6
    return 0;
}

注:位操作符的操作数只能是整数。

//不能创建临时变量(第三个变量)
//实现两个数的交换。
#include <stdio.h>
int main()
{
    int a =3;//011
    int b =5;//101
    
    //创建临时变量
    //int tmp = 0;
    //printf("before:a=%d\n b=%d\n", a, b);
    //tmp = a;
    //a = b;
    //a = tmp;
    //printf("after:a=%d\n b=%d\n", a, b);
    
    //加减法
    //缺陷:过于大,超出表达范围,会丢失,可能会溢出
    //a = a + b;
    //b = a - b;
    //a = a - b;
    //printf("a = %d b = %d\n", a, b);

    //异或
    //不会溢出
    a = a ^ b;//110
    b = a ^ b;//011
    a = a ^ b;//101
    printf("a = %d b = %d\n", a, b);
    return 0;
}
//编写代码实现
//求一个整数存储在内存中的二进制中1的个数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
    int num = 0;
    scanf("%d", &num);
    //统计num的补码中有几个1
    int count = 0;
    while (num)
    {
        if (num % 2 == 1)//余数
            count++;
        num = num / 2;//去个位数
    }
    printf("二进制中1的个数 = %d\n", count);
    return 0;
}
//优化,可以计算负数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
    int num = 0;
    scanf("%d", &num);
    int i = 0;
    int count = 0;//计数
    for (i = 0; i < 32; i++)
    {
        //if (num & (1 <<i))
        if (1==((num >> i)&1))
        //32bit
        //num & 1==1即第一位为1
            count++;
    }
    printf("二进制中1的个数 = %d\n", count);
    return 0;
}

(4) 赋值操作符

初始化:变量创建给一个值

赋值:变量有一个值,再给一个值

复合赋值符

+=( a = a + 2 / a + = 2 )

-=      *=       /=      %= 

>>= ( a >> = 1 / a = a >> 1)

<<=    &=     |=      ^=

(5)单目操作符

只有一个操作数

!           逻辑反操作(假变成真,真变成假)

#include <stdio.h>
int main()
{
    int a = 0;
    if (a)
    {
        printf("xi\n");
    }
    if (!a)
    {
        printf("hehe\n");
    }
    return 0;
}

-           负值( a = - 5 / a = - a )

+           正值

&           取地址(与指针搭配)

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

#include <stdio.h>
int main()
{
    int a = 10;
    int* p = &a;
    *p = 20;
    return 0;
}

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

为类型,不能去掉括号

#include <stdio.h>
int main()
{
    int a = 10;
    char c = 'r';
    char* p = &c;
    int arr[10] = { 0 };
    //内存所占空间的大小,单位是字节
    printf("%d\n", sizeof(a));//4(a为整型,占4字节
    printf("%d\n", sizeof(int));//4

    printf("%d\n", sizeof(c));//1(c为一个字符)
    printf("%d\n", sizeof(char));

    printf("%d\n", sizeof(p));//4(p为指针,4或8)
    printf("%d\n", sizeof(char*));

    printf("%d\n", sizeof(arr));//40(数组为10个元素,每个元素四个字节)
    printf("%d\n", sizeof(int [10]));
    return 0;
}
#include<stdio.h>
int main()
{
    short s = 0;
    int a = 10;
    printf("%d\n", sizeof(s = a + 5));//2 s是短整型
    printf("%d\n", s);//0 上面表达式不直接参与运算
    return 0;
}

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

#include<stdio.h>
int main()
{
    int a = 11;//1011
    a = a | (1 << 2);
    printf("%d\n", a);//15
    a = a & (~(1 << 2));
    printf("%d\n", a);//11

    //int a = 0;
    //~按(二进制)位取反
    //00000000000000000000000000000000
    //11111111111111111111111111111111--补码
    //11111111111111111111111111111110--反码
    //10000000000000000000000000000001--原码
    //printf("%d\n", ~a);
    return 0;
}

--          前置--(先--,后使用)、后置--(先使用,后--)

++          前置++(先++,后使用)、后置++(先使用,后++)

(类型)       强制类型转换  // int   a  =  ( int ) 3.14  ;

(6)sizeof 和 数组

#include <stdio.h>
void test1(int arr[])//指针接收
{
    printf("%d\n", sizeof(arr));//4
}
void test2(char ch[])
{
    printf("%d\n", sizeof(ch));//4
}
int main()
{
    int arr[10] = { 0 };
    char ch[10] = { 0 };
    printf("%d\n", sizeof(arr));//40--1个整型4个字节,10*4=40
    printf("%d\n", sizeof(ch));//10
    test1(arr);//传递是首元素地址
    test2(ch);
    return 0;
}

(7)关系操作符

>大于

>=大于等于

<小于

<=小于等于

!=   用于测试“不相等”

==      用于测试“相等”

(8)逻辑操作符

&&     逻辑与(都为真,则为1;一个假,则为0)

||        逻辑或(都为假,则为0;一个真,则为1)

#include <stdio.h>
int main()
{
    int a = 0;
    int b = 5;
    int c = a && b;
    int d = a || b;
    printf("%d\n", c);//0
    printf("%d\n", d);//1
    return 0;
}
#include <stdio.h>
int main()
{
    //int i = 0, a = 0, b = 2, c = 3, d = 4;
    //i = a++ && ++b && d++;//1 2 3 4 
    //a先使用,后++
    //由于左边为假,右边不再计算
    int i = 0, a = 1, b = 2, c = 3, d = 4;
    i = a++||++b||d++;//2 2 3 4
    //a=1,即为真,后面不用计算
    printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
    return 0;
}

(9) 条件操作符

exp1 ? exp2 : exp3

表达式1为真,即表达式2为结果

表达式1为假,即表达式3为结果

#include <stdio.h>
int main()
{
    int a = 0;
    int b = 0;
    /*if (a > 5)
        b = 3;
    else
        b = -3;

    b = (a > 5 ? 3 : -3);*/
    int max = 0;
    if (a > b)
        max = a;
    else
        max = b;

    max = (a > b ? a : b);
    return 0;
}

(10)逗号表达式

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

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

int a = 1;
    int b = 2;
    int c = (a > b, a = b + 10, a, b = a + 1);
           //无结果,12=2+10;12;13=12+1
    printf("%d\n", c);//13

    if (a = b + 1, c = a / 2, d > 0)
        //判断d是否大于0,大于0,前面为真,否则为假

    a = get_val();//函数放于a中
    count_val(a);
    while (a > 0)
    {
        //业务处理
        a = get_val();
        count_val(a);
    }
    //优化
    while (a = get_val(), count_val(a), a > 0)
    {
        //业务处理
    }

(11) 下标引用、函数调用和结构成员

1. [ ] 下标引用操作符

操作数:一个数组名 + 一个索引值

#include<stdio.h>
int main()
{
    int arr[10] = { 0 };//创建数组
    arr[4] = 10;//实用下标引用操作符
    return 0;
}

2.( ) 函数调用操作符

#include <stdio.h>
int get_max(int x, int y)
//这个括号不是函数调用操作符
{
    return x > y ? x : y;
}
int main()
{
    int a = 10;
    int b = 20;
    int max = get_max(a, b);
    //调用函数的时候的()就是函数调用操作符
       //操作数为a,b,get_max,有三个
    printf("max=%d\n", max);
    return 0;
}

3. 访问一个结构的成员

. 结构体.成员名

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

#include <stdio.h>
//类型:结构体类型
struct Stu
{
    //成员变量
    char name[10];
    int age;
    char id[20];
    double score;
};
int main()
{
    //使用strut Stu的类型创建一个学生对象s1,并初始化
    struct Stu s1 = {"曾",20,"201851520"};
    struct Stu* ps = &s1;
    printf("%s\n",ps->name);
    printf("%d\n", ps->age);
    /*printf("%d\n", (*ps).name);
    printf("%s\n", s1.name);
    printf("%d\n", s1.age);
    printf("%s\n", s1.id);*/
    return 0;
}

二、表达式求值

表达式求值的顺序一部分是由操作符的优先级和结合性决定。

同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型

(1)隐式类型转换

整型提升:C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型。

如何进行整体提升呢? 整形提升是按照变量的数据类型的符号位来提升的

#include <stdio.h>
int main()
{
    char a = 3;
    //a中存放00000011
    //提升加0
    char b = 127;
    //b中存放01111111
    char c = a + b;
    //c=a+b=10000010
    //补码111111...11110000010
    //反码111111...11110000001(减一)
    //原码100000...00001111110(取反)
    printf("%d\n", c);//-126
    //%d,即打印整型
    return 0;
} 
#include<stdio.h>
int main()
{
    //定义
    char a = 0xb6;//char 1字节
    //b6,b=10,两个十六进制的数,二进制为10110110
    
    short b = 0xb600;//short 2字节
    int c = 0xb6000000;//int 4字节
    if (a == 0xb6)//会补1
        printf("a");
    if (b == 0xb600)
        printf("b");
    if (c == 0xb6000000)
        printf("c");//c
    return 0;
}
#include<stdio.h>
int main()
{
    char c = 1;//char是1字节
    printf("%u\n", sizeof(c));//1
    printf("%u\n", sizeof(+c));//4
    printf("%u\n", sizeof(-c));//4
    //整型提升,即计算的整型大小
    printf("%u\n", sizeof(!c));//1
    return 0;
}

(2)算术转换

个操作符的各个操作数属于不同的类型,将其中一个操作数的转换为另一个操作数的类型

long double 8字节

double 8字节

float 4字节

unsigned long int 4字节

long int 4字节

unsigned int 4字节

int 4字节

上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运 算

(3)操作符的属性

复杂表达式的求值有三个影响的因素

1. 操作符的优先级

2. 操作符的结合性

3. 是否控制求值顺序(是否继续运算)

#include<stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    int c = b + a * 3;
    //操作符的优先级
    //+和=优先级相同,比*优先级低
    int d = a + b + c;
    //优先级一致
    //操作符的结合性
    return 0;
}

问题表达式

a*b + c*d + e*f;

计算顺序,不知道最先开始哪个,没有唯一计算路径

 

c + --c ;

--优先级比+高,+操作符的左操作数c的值,可能是--c后,也可能是--c前获取,是有歧义的。

ret = (++i) + (++i) + (++i) ;

answer = fun() - fun() * fun() ;

 

标签:include,return,int,C语言,第五章,操作符,printf,main
来源: https://www.cnblogs.com/mljrm/p/15440476.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有