C与指针——操作符和表达式(一)

5.1 操作符

5.1.1算数操作符

加(+) 减(-) 乘(*) 除(/) 取模(%)
%: 取模运算符,接受两个整型操作数,把左操作数除以右操作数,返回的值为余数(非商)。
/: 当该操作符的两个操作数都是整数时,执行整除运算,否则执行浮点数除法。

5.1.2 移位操作符

在这里插入图片描述
无符号值执行的所有移位操作都是逻辑移位;
有符号的值执行的移位操作取决于编译器(一个有符号的右移位操作不可移植)。

5.1.3 位操作符

AND操作[ & ]:如果两个位都是1,结果为1,否则结果为0。(均1为1)
OR操作[ | ]:如果两个位都是0,结果为0,否则结果为1。(均0为0)
XOR(异或)操作[ ^ ]:如果两个位不同,结果为1;如果两个位相同,结果为0。(相异为1相同为0)
它们都要求操作数为整数类型。
单目操作符~:用于对其操作数进行求补运算,即1变0,0变1。

5.1.4 赋值

赋值操作符=:把右操作数的值存储于左操作数指定的位置。其结合性的求值顺序为从右至左。左值意味着一个位置,右值意味着一个值。
复合赋值符+=:把ex加到a。

a+=ex;  //操作数只求值一次
/*相当于*/  a=a+(ex);
5.1.5单目操作符

!——逻辑反操作
~——求补操作
&——产生操作数的地址(返回一个指向它的操作数的指针)
*——间接访问操作符(操作数必为指针)
sizeof——判断操作数的类型长度(返回操作数的类型长度,单位为字节)
(类型)——强制类型转换
补充:

Sizeof与Strlen的区别与联系
1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。
该类型保证能容纳实现所建立的最大对象的字节大小。
2.sizeof是运算符,strlen是函数。
3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以’’\0’‘结尾的。
sizeof还可以用函数做参数,比如:
short f();
printf("%d\n", sizeof(f()));
输出的结果是sizeof(short),即2。
4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
5.大部分编译程序,在编译的时候就把sizeof计算过了,是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因。
char str[20]=“0123456789”;
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
6.strlen的结果要在运行的时候才能计算出来,是用来计算字符串的长度,不是类型占内存的大小。
7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是一个操作符而不是一个函数。
8.当适用于一个结构类型或变量时, sizeof 返回实际的大小;
当适用于一个静态的空间数组时, sizeof 归还全部数组的尺寸。
sizeof 操作符不能返回动态被分派了的数组或外部数组的尺寸
9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,
如:
fun(char [8])
fun(char [])
都等价于 fun(char )
在C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小
如果想在函数内知道数组的大小, 需要这样做:
进入函数后用memcpy拷贝出来,长度由另一个形参传进去
fun(unsiged char p1, int len)
{
unsigned char
buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}
我们能常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度。
看了上面的详细解释,发现两者的使用还是有区别的,从这个例子可以看得很清楚:
char str[20]=“0123456789”;
int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。
int b=sizeof(str); //而 b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,不受里面存储的内容改变。
上面是对静态数组处理的结果,如果是对指针,结果就不一样了
char
ss = “0123456789”;
sizeof(ss) 结果 4 ===>ss是指向字符串常量的字符指针,sizeof 获得的是一个指针的之所占的空间,应该是
长整型的,所以是4
sizeof(*ss) 结果 1 ===>*ss是第一个字符 其实就是获得了字符串的第一位’0’ 所占的内存空间,是char类
型的,占了 1 位
strlen(ss)= 10 >>>> 如果要获得这个字符串的长度,则一定要使用 strlen

++、-- ——增值操作符、减值操作符
在操作数之前的操作符在变量值被使用之前增加(减少)它的值;在操作数之后的操作符在变量值被使用之后才增加(减少)它的值。

int a,b,c,d;
...
a=b=10; //a,b得到值10
c=++a;  //a增加至11,c得到的值为11   ++a的结果是a值的拷贝,并非变量本身
d=b++;  //b增加至11,d得到的值仍为10
5.1.6 关系操作符

用于测试操作数之间的各种关系。> >= < <= != ==(相等性)
这些操作符产生的结果都是一个整型值,而非布尔值。若两端操作数符合操作符指定关系,表达式结果为1(非零值为真);若不符合,表达式结果为0(假)。可在if或while中作为测试表达式。

5.1.7 逻辑操作符(短路求值)

&&:均真为真
||:有真为真
位操作符(&和|)与逻辑操作符的区别:
1.逻辑操作符具有短路性质,即表达式的值如果可以根据左操作数决定,便不再对右操作数进行求值,而位操作符两边操作数都需进行求值;
2.逻辑操作数用于测试零值和非零值,而位操作符用于比较它们操作数中对应的位。

5.1.8 条件操作符
ex1 ? ex2 : ex3 
 //若ex1的值为真,表达式的值为ex2的值;若ex1得值为假,表达式为ex3的值。
5.1.9 逗号操作符
ex1,ex2,...,exn
//将两个或多个表达式分隔开,自左向右逐个求值,最后的表达式值为整个逗号表达式的值。

5.2 布尔值

C并不具备显式的布尔类型,所以用整数来代替。
零是假,任何非零值皆为真。

nonzero_a=a!=0;
...
if(nonzero_a==(b!=0))...//当a和b的值都是零或者都非零时,测试结果为真

if(nonzero_a==b)...//当b为某个特定的整型值时,测试结果为真

注意:
1.尽量避免混合使用整型值和布尔值;
2.不要使用简写法来测试变量是零还是非零(错误暗示变量为布尔型);
3.不通过把它与任意特定值进行比较来测试变量是否为真。

5.3 表达式求值

隐式类型转换(整形提升):C的整型算术运算总是至少以缺省整型类型的精度进行。为获得该精度,表达式中的字符型和短整型在使用之前被转换为普通整型。

寻常算术转换:

long double 
double
float
unsigned long int
long int
unsigned int
int 
//若某操作数排名较低,则它首先将转换为另一个操作数的类型然后执行操作。

在这里插入图片描述
操作符优先级
(优先级只对相邻操作符的执行顺序起作用)
在这里插入图片描述在这里插入图片描述

编程练习

1.

编写一个程序,从标准输入读取字符,并把它们写到标准输出中。除了大写字母字符要转换为小写字母之外,所有字符的输出形式应该和他们的输入形式完全相同。

程序如下:

//  方法一
#include<stdio.h>
void main()
{
	char ch;
	while((ch=getchar())!=EOF)
	{ 
	    if(ch>='A'&&ch<='Z')
	    {ch+=32;
		putchar(ch);
		}
	    else 
	    putchar(ch);
	}
}
//  方法二
#include<stdio.h>
#include<ctype.h>
int main()
{
	char ch;
	while((ch=getchar())!=EOF)
	{ 
	    putchar(tolower(ch));
	}
	return 0;
}
//  方法三
#include<stdio.h>
void main()
{
	int ch;
	while((ch=getchar())!=EOF)
	{ 
	    if(ch>=65&&ch<=90)
	    {ch+=32;
		putchar(ch);
		}
	    else 
	    putchar(ch);
	}
}

运行结果:
在这里插入图片描述

注: 方法二中所使用的tolower是一种函数,功能是把字母字符转换成小写,非字母字符不做出处理。和函数int _tolower( int c )功能一样,但是_tolower在VC6.0中头文件要用ctype.h。

2.

编写一个程序,从标准输入读取字符,并把它们写到标准输出中。所有非字母字符都完全按照它的输入形式输出,字母字符在输出前进行加密。
加密方法很简单:每个字母被修改为在字符表上距其13个位置(前或后)的字母。例如,A被修改为N,B被修改为O,Z被修改为M,以此类推。注意大小写字母都应该被转换。提示:记住字符实际上是一个较小的整型值这一点可能对你有所帮助。

程序如下:

#include<stdio.h>
void main()
{
	int ch;//这里的ch,整型与字符型都可使用
	while((ch=getchar())!=EOF)
	{ 
	    if((ch>=65&&ch<78)||(ch>=97&&ch<110))
	    //  if((ch>='A'&&ch<'N')||(ch>='a'&&ch<'n'))
	    ch+=13;
	    else if((ch>=78&&ch<=90)||(ch>=110&&ch<=122))
	    //  else if((ch>='N'&&ch<='Z')||(ch>='n'&&ch<='z'))
	    ch-=13;
	    putchar(ch);	    
	}
}

运行结果:

在这里插入图片描述

最离奇的是那看起来高耸入云的辉煌圣地所需要的建筑材料竟然是平日里最枯燥乏味碌碌平庸且不间断的努力。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值