一.C#位运算符
位运算符作用于位,并逐位执行操作。&,|,^的真值表如下所示:
假设 a=60,b=13现在以二进制表示,则a=0011 1100,b=0000 1101。则a&b=0000 1100, a|b=0011 1101
a^b=0011 0001, ~a=1100 0011
PS:1.其中~为按位取反运算符,具有翻转效果,即0变成1,1变成0
2.<<表示二进制左移运算符。左操作数得值向左移动右操作数指定位数。如a<<2表示1111 0000
同理a>>2表示0000 1111
&,|,^除了能用于位运算,还能用逻辑运算分别对应与,或,异或。对于bool类型其值与上述真值表一样。
二.C#其他的运算符
sizeof() 返回数据类型大小
typeof() 返回class的类型
& 返回变量的地址
* 变量的指针
?: 条件表达式 。如果条件为真?则为X:否则为Y
is 判断对象是否为某一类型
as 强制转换,即使转换失败也不会抛出异常。
x?y:z 表示如果表达式x为true,则返回y,否则返回z。(等同于c中if{}else{})
三.C编程遇到的小问题
1.
编程设计一个简单的计算器程序,要求用户从键盘输入如下形式的表达式:操作数1 运算符op 操作数2。然后,计算并输出表达式的值指定的运算符为: 加(+)减(-)乘(*)除(/)代码如下,所给程序是否存在错误,若有,找出错误所在并改正。
代码如下
#include <stdio.h>
int main()
{
float data1, data2;
char op;
printf("Please enter the expression:");
scanf("%f %c%f", &data1, &op, &data2); /* %c前有一个空格 */
switch (op)
{
case '+':
printf("%f + %f = %f\n", data1, data2, data1 + data2);
break;
case '-':
printf("%f - %f = %f\n", data1, data2, data1 - data2);
break;
case '*':
printf("%f * %f = %f\n", data1, data2, data1 * data2);
break;
case '/':
printf("%f/%f = %f\n", data1, data2,data1/data2);
break;
default:
printf("Invalid operator!\n");
}
return 0;
}
已知除法中除数不能为0,所以应修改case '/'。第一次尝试将case '/'中代码修改为以下
if(data2==0)
printf("Division by zero!\n");
else
printf(%f/%f=%f\n",data1,data2,data1/data2);
虽然代码能够运行但是已知float类型=0其实代表的是无限趋近于0的浮点数.所以为了更准确表示可采用以下方法。
#include <stdio.h>
#include <math.h>
#define EPS 1e-6
int main()
{
float data1, data2;
char op;
printf("Please enter the expression:");
scanf("%f %c%f", &data1, &op, &data2); /* %c前有一个空格 */
switch (op)
{
case '+':
printf("%f + %f = %f\n", data1, data2, data1 + data2);
break;
case '-':
printf("%f - %f = %f\n", data1, data2, data1 - data2); break;
case '*':
printf("%f * %f = %f\n", data1, data2, data1 * data2);
break;
case '/':
if (fabs(data2)<=EPS)
printf("Division by zero!\n");
else
printf("%f/%f = %f\n", data1, data2,data1/data2);
break;
default:
printf("Invalid operator!\n");
}
return 0;
}
switch-case语句中每一个case执行完后如果不加break;则会继续执行下一个case直到遇见break或者执行完所有的case跳出switch-case。否则会造成以下代码的情况。
#include <stdio.h>
int main(){
int a=1,b=0;
switch(a){
case 1:
switch (b)
{
case 0:
printf("**0**");
break; //有break跳出switch-case
case 1:
printf("**1**");
break;
} //最外层的switch-case中case 1没有break,所以会继续执行case2
case 2:
printf("**2**"); //输出结果为**0****2**
break;
}
return 0;
}
2.
数组排序中的插入排序。
#include <stdio.h>
#define lenth 100 /*输入一个数组的大小*/
int main(){
int a[lenth],i,j,k,y;
for(i=0;i<lenth;i++){ /* 如何输入一个数组*/
scanf("%d",&a[i]);
}
for (k=1;k<lenth;k++){ /*插入排序:在待排序的元素中,对前n-1个元素排序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序。
所以a[0]一个元素算有序,所以k=1,从第二个元素排序.之后每插入一个元素都必须与前面排好序数组按个比较*/
y=a[k];
j=k-1;
while(j>=0 && a[j]>y){
a[j+1]=a[j];
a[j]=y;
j--;
}
}
for (i=0;i<lenth;i++){
printf("%d ",a[i]);
}
return 0;
}