C系统梳理2——字符串、操作符、表达式求值、关键字

五、字符串、转义字符和注释

1、字符串

定义:由双引号引起来的一串字符。除非特别定义,默认初始化会给结尾加上结束标志。注意:它的结束标志是 ‘\0’ 的转义字符,在计算字符串长度时不作内容。( 为了说清这一点,通过使用strlen ( ) 和sizeof ( ) 来对比 )
strlen ( ) 是用来求字符串有效长度的函数,长度的结束标志符是 ‘\0’ 。而sizeof是用来计算变量所占空间大小的操作符,与 ‘\0’ 无关。下面具体举例:

char arr1[] = "zuo";    //一般情况
char arr2[] = {'z','u','o'};    //对于strlen ( )结束不了
char arr3[] = {'z','u','o','\0'};    //对于sizeof ( ) ,'\0'也要计入

这段字符串的定义,如果使用strlen ( ) ,那它的结果分别为3,随机数,3;如果使用sizeof,那它的结果分别为4,3,4.

2、转义字符

转义字符属于字符型常量,所以在使用时需要用单引号引起来。转义
字符再加上一个 \ 就会变成普通字符。下面是常见的一些转义字符:
这是常见的一些转义字符
这里来做一个经典的题目:

int main()
{
    printf("%d\n",strlen("c:\test1\678\name"));//这里输出是多少?
    return 0;
}

这个题的答案是13,你做对了吗?思路:这个字符串里面有转义字符 ‘\t’ , ‘\67’ , ‘\n’ 。因为8不属于八进制,所以它单独算作一个长度。

3、注释

注释有两种,一种是/* */,还有一种是//。
前者有一个特点就是会寻找离它最近的第一个 */,把这一段注释掉,所以不可以嵌套使用。这也是它的一个缺点。

六、三大语句及函数,数组

一般语言的三大语句是顺序,选择(分支),循环。C语言也不例外。

函数的作用就是为了对代码进行简化和复用。一个函数只有一个返回值。函数可以嵌套调用,但是不可以嵌套定义!传值调用时改变形参不影响实参,传址调用会影响。函数不调用时形参没有内存空间,调用时才开辟空间。

数组的下标是从0开始的。

这部分由于内容较多,以后再做赘述,这里只是简单的列出框架。

七、操作符

1、算术操作符

 +   -   *   /   %

需要注意的是 ,对于除法运算,表达式都是整型,结果也是整型;只要出现浮点型,结果就是浮点型;对于取余运算,要求均为整型。

2、移位操作符

>>   <<

分别是左移和右移。作移位运算时,移动的是其二进制位。(注意:移到的位数非负,不可以移动负数位)
左移:左边舍弃,右边补零。
右移:逻辑右移是左边补零,右边舍弃;算术右移是左边补符号位,右边舍弃。

3、位操作符

&   ⋀   |

分别是与,异或,或。作位运算是按其二进制位进行运算。

  • 例题:不创建中间变量,直接实现两个变量的值交换。
#include<stdio.h>
int main()
{
	int a = 2;
	int b = 3;
	a = a ^ b;
	b = a ^ b;    //a ^ b = (a ^b) ^ b = a ^ (b ^ b) = a ^ 0 = a
	a = a ^ b;    //a ^ b = (a ^b) ^ a = (a ^ a) ^ b = 0 ^ b = b
	printf("a = %d,b = %d\n", a, b);
	return 0;
}

交换

  • 求一个整数存储在内存中的二进制位中的 1 的个数
#include<stdio.h>
int main()
{
	int num1 = 8;
	int num2 = -2;
	int count = 0;

	//方法一 不可以计算有符号负数
	/*while (num1)
	{
		if ( (num1 % 2) == 1)
			count++;
		num1 /= 2;
	}*/


	//方法二 都可以计算,但是每次都要循环32遍,比较浪费资源
	/*int i = 0;
	for (i = 0; i < 32; i++)
	{
		if (((num2 >> i) & 1) == 1)    //把数字右移与1相与,为1为真否则为假
		{
			count++;
		}
	}*/

	//方法三 优化完毕
	while (num2)
	{
		count++;
		num2 &= (num2 - 1);
	}
	printf("1的个数是:%d\n", count);

	return 0;
}

4、赋值操作符

=   +=   -=     *=   /=   &=   ⋀=   |=   >>=   <<=

5、单目操作符

只需要一个操作数的操作符叫单目操作符。

!   逻辑反操作
 1.    负值
 2.    正值
&    取地址
sizeof   计算变量或变量名所占空间大小,字节为单位
~    对一个数的二进制位按位取反
++    前置加一和后置加一
--    前置减一和后置减一
 3.    间接访问操作符也叫解引用操作符
(类型)     强制类型转换

这里主要摘出来说一下以下几个:

(1)整型a的值为0,那么~a的值是?-1

思路:计算机内部采用的是补码进行运算,a的二进制补码为32位0。

00000000 00000000 00000000 00000000    a的补码
11111111 11111111 11111111 11111111    ~a的补码
减一取反得到
10000000 00000000 00000000 00000001    即-1

(2)对于前置和后置运算(它是一个表达式),前置时先+1(或-1),再使用值;后置时先使用值再+1(或-1)

(3)对于强制类型转换操作符,用法如下:

int a = (int)1.5;  //此时a的值为1

6、关系操作符

>   >=   <   <=   !=   ==

这里需要注意的是,一个 = 表示赋值,两个 = 才是判断关系。

7、逻辑操作符

&&   ||   !

分别表示逻辑中的与,或,非。

  • 例题:求输出结果?
#include<stdio.h>
int main()
{
    int i = 0,a = 0,b  = 2,c = 3,d = 4;
    i  = a++ && ++b && d++;
    //i  = a++ || ++b || d++;
    printf("%d %d %d %d \n",a,b,c,d);
    return 0;
}
  • && 时,值为 1,2,3,4(只要判断为假,&&运算就不会再往后计算了,所以只给a作了自加1)
  • || 时,值为1,3,3,4(只要判断为真,|| 运算就不会再往后计算了,所以当计算到 b 时,已经为真,就不会再给d 作自加1)

8、其它操作符

< exp1 >?< exp2 >:< exp3 >      //条件操作符(三目)
,    //逗号操作符
[ ]    //下标引用操作符,用于数组
( )    //函数调用操作符,跟在函数名后面
.    //直接访问结构体成员变量使用;结构体名.成员变量名
->    //通过结构体指针访问结构体成员变量使用;结构体指针名->结构体成员变量名

这里说以下几个:

  • 条件操作符 : exp1为条件,条件为真执行exp2,条件为假执行exp3。
  • 逗号操作符 : 用在逗号隔开的一串表达式,从左向右依次计算,结果是最后一个表达式结果。

八、表达式求值

求值顺序一部分由运算符的优先级和结合性决定。有些表达式的操作数在求值过程中有可能需要转化为其他类型。下面介绍两种隐式转换:

1、整型提升

CPU内整型运算器(ALU)的操作数的字节长度及通用寄存器的字节长度都是4个字节。因此,即使两个char型的数据相加,CPU实际执行时也要先转化为整型操作数标准长度。

通用CPU难以实现两个8bite直接相加运算,所以整型算术运算的表达式中的 char 和 short 类型的操作数在使用前要转换为 int 型,这种转换就叫整型提升

  • 整型提升的方法:有符号数,高位补充符号位;无符号数高位补0
  • 实例:
    整型提升实例
  • 注意:整型表达式进行计算时先做整型提升,再计算。例子如下:
int main()
{
    char a = 0xa1;
    short b = 0xa123;
    int c = 0xa1234567;
    
    if( a == 0xa1 )
    {
        printf("a\n");
    }
    if( b == 0xa123 )
    {
        printf("b\n");
    }
    if( c == 0xa1234567 )
    {
        printf("c\n");
    }

    return 0;
}

在这里插入图片描述
只输出 c 的原因:做条件判断整型表达式,a 和 b 进行了整型提升,变成了负数,结果为假;而 c 本来就是 int 型,不需要整型提升,结果为真。

2、算术转换

某个操作符的操作数属于不同数据类型,必须要把一个操作数转换为另一个操作数类型,否则操作无法进行。操作数的参差体系如下:
long double > double > float >unsigned long int > long int > unsigned int > int

九、关键字

c语言标准32个关键字如下:
关键字
这里主要摘出这几个说一下:

auto:自动变量就是自动创建,自动销毁的变量。局部变量即自动变量。

typedef:给类型重命名。

typedef unsigned int unit;   //将unsigned int重命名为uint

static:用来修饰变量和函数的关键字。
1)修饰局部变量,改变局部变量的生命周期,使其与程序的生命周期一样。

#include <stdio.h>
int Add()
{
    static int i = 0;
    i++;
    return i; 
}

int main()
{
    int i = 0;
    for(i = 0;i < 5; i++)
        test();
    return 0;
}

本来对于变量 i 它的生命周期只有在Add函数内部,所以输出为五个1;在ADD函数内给 i 加上static关键字之后就它的生命周期变成了程序的生命周期,输出变成了1到5。

2)修饰全局变量,改变了全局变量的作用域,使得只能在自己的源文件中使用。
在其他源文件的内部是看不到或者说使用不了的。
3)修饰函数,改变了函数的使用范围,使得只能在自己的源文件中使用。
同样,在其他源文件的内部是看不到或者说使用不了的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值