C语言C语言程序员

C语言注释符号一本道来

2017-12-03  本文已影响33人  PcDack
符号与注释.png

注释符号

一个好的注释

akari.png

好的注释(摘自网络)

exp:初探注释规则

#include <stdio.h>

int main()
{
    int/*...*/i;//编译器对注释的处理不是简单的删除,而是用空格来代替
    char* s = "abcdefgh      //hijklmn";//注释符号是不能在双引号之间的
    
    //Is it a \//'\'反斜杠可以当作换行符号
    valid comment?
    
    in/*...*/t i;
    
    return 0;
}

结论


一个不安宁的反斜杠(接续符号和转义符号)

接续符号:\(反斜杠)

最佳实例

#include\
<stdio.h>
int main(){
        printf\
("hello");
}

编译预处理后

int main(){
 printf("hello");
}

很明显可以看出来,编译预处理的时候将接续符去掉,将下一行补上来。这种用法常用在宏函数

接续符号的作用

举个栗子

#include<stdio.h>
void swap(int a,int b)
{
        int temp=a;    
    a=b;        
    b=temp;        
}
//下面就是宏函数
#define SWAP(a,b)  \
{                  \
    int temp=a;    \
    a=b;           \
    b=temp;        \
}
void main()
{
    int a=10,b=20;
    SWAP(a,b);
    printf("a=%d\nb=%d\n",a,b);
}

转义符号

转义符号用来表示无回显的符号

转义符号.png

小结


单身狗与双生人(单引号和双引号)

最佳示例

#include<stdio.h>
void main()
{
    char * p1=1;      //指向内存地址为一的位置(野指针)
    char * p2='1';    //指向1的ASCALL码的位置也就是内存中49为 (野指针)
    char * p3="1";    //真正指向一字符串的位置
        printf('\n');//printf的参数是字符类型的首地址指针,也就是调用\n所在位置的地址的指针
}

从上面的注释和例子可以得到这样几个结论


逻辑运算符使用分析

&& 和||

最佳示例

#include<stdio.h>
void main()
{
    int i=0;
    int j=0;
    if(++i>0 || ++j>0)
    {
        printf("%d\n",i);
        printf("%d\n",j);
    }
}

输出的结果是1,0.下面来解释原因

程序的短路规则

!

最佳示例

#include<stdio.h>
void main()
{
    printf("%d\n",!0);
    printf("%d\n",!1);
    printf("%d\n",!100);
    printf("%d\n",!-1000);
}

答案 1,0,0,0

结论:

C语言中的逻辑“!”只认得“0”,只知道0取非为1,若果不为0,结果都为0

三目运算符

最佳示例

假设有a,b三个变量,如果a>b,那么给a赋值为3。

我脑中第一个闪过的程序是a<b? &a=3:&b=3;然后emmmmmm,报错,于是,就觉得C语言的三目运算符有点搞头。查了一些blog才知道,真正的写法是*(a<b? &a:&b)=3;

#include<stdio.h>
void main()
{
    int a=0;
    int b=2;
    int c=1;
    *(a<b? &a:&b)=3;
    printf("%d\n",a);
    printf("%d\n",b);
    printf("%d\n",c);
}

总结

不要被其他语言带翻车


位运算符号分析

位运算种类

位运算.png

运算法则(和数学一样)

防错准则

运算小技巧

技巧一

最佳示例

使用左移的方法

#include<stdio.h>
#include<time.h>
void main(){
        int h,e;
        h=clock();
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        printf("%d\n",256>>4);
        e=clock();
        printf("%d毫秒\n",e-h);
}

结果113毫秒

使用除法

#include<stdio.h>
#include<time.h>
void main(){
        int h,e;
        h=clock();
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        printf("%d\n",256/16);
        e=clock();
        printf("%d毫秒\n",e-h);
}

结果141毫秒

结论

我这里只用十次除法。虽然看似毫秒只差,但是一旦到项目中运算量大的时候,失之毫秒,差之千秒,至于原因,是因为计算机是二进制的玩意。它似乎更喜欢处理位运算

技巧二

最佳示例


#include<stdio.h>
#define SWAP1(A,B)\
{          \
int temp=A;\
A=B;        \
B=temp;      \
}
#define SWAP2(a,b)\
{\
a=a+b;\
b=a-b;\
a=a-b;\
}
#define SWAP3(a,b)\
{\
a=a^b;\
b=a^b;\
a=a^b;\
}
int main()
{
    int a=10,b=20;
    SWAP1(a,b);
    SWAP2(a,b);
    SWAP3(a,b);
    printf("a=%d,b=%d\n",a,b);
    
    
}

一共三种方法进行位置交换

优缺点表

方法 优点 缺点
SWAP1 无论什么类型的都可以 效率十分的底下
SWAP2 效率相对较高 容易溢出,效率一般,类型只能是整型
SWAP3 效率非常高 类型只能是整型,推荐使用

最佳实战

题目:2,3,5,7,2,2,2,5,3,7,1,1,1找出基数个的数字(也就是1)

思路:用亦或的方法最好,因为偶数个亦或等于零,所以,所有的数字亦或的结果剩下的数字就是我们要找的数字

#include<stdio.h>
#define DIM(a)\
(sizeof(a)/sizeof(*a))
void main()
{
    int a[]={2,3,5,7,2,2,2,5,3,7,1,1,1};
    int i=0;
    int answer=0;
    for(i=0;i<DIM(a);i++)
    {
        answer=a[i]^answer;
    }
    printf("the result is %d\n",answer);
} 

注意

如果移位超过他最大的位数,那么结果为0,例如:1<<32的结果为0

移动位数为负数的结果是0,例如:1<<-1的结果为0


++,- -操作符号的分析(头疼地带)

int i=3;
(++i)+(++i)+(++i)=?

这里有两种解释:

  1. ++i是平等的一共有3个,需要加三次,所以是18(3x6)
  2. 先处理两个,然后再加后一个里面的内容,前两个加完为10,再加一个的话就为16(如果是Linux开发是这种,准没错。在gccg++测试通过)

逗号表达式如何计算

规则:从左算到右顺序求值,最后一个表达式的值就是逗号表达式的值

最佳示例

int x=4;
int k=(++i,i++,i+10);

结果16,没什么好说的


如何检验程序是否正确?贪心法

分析++i+++i

第一步:++i,到第二步++i+,到第三步++i++,很显然如果用贪心法分析,程序是错的 .事实证明程序确实是错的.


优先级和类型转换分析

C语言中的优先级(常产生的错误)

优先级转化


优先级.png
#include<stdio.h>
#include<malloc.h>
typedef struct _dome{
    int * pInt;
    float f;
} DOME;
int func(int i,int j)
{
    return (i&j !=0);//因为比较符号的优先级高于按位符号所以,这里的输出结果为先判断m!=0然后,再按位与
}
void main()
{
    DOME *pD=(DOME*)malloc(sizeof(DOME));
    int *p[5];//这里相当于int* p[5];
    int *f();//这里相当于 int* f();
    int i=0;
    i=1,2;//逗号表达式应当加括号
    *pD.f=1;//这里相当于pD.f=1后的指针
    free(pD);
    
}

注释里把需要解释的都注释好了,一看就懂

C语言隐式类型转换

隐式优先级表


隐式优先级.png
short c=1;
char b=0;
c+b 的类型?

c+b为short类型

最佳示例

#include<stdio.h>
void main()
{
    int i=-2;
    unsigned int j=1;
    if((i+j)>0)//看上面的图片可以知道int类型先变成unsigned类型进行计算
    {
        printf("i+j>0");
    }else
    {
        printf("<0");
    }
    printf("%d",i+j);
}
上一篇 下一篇

猜你喜欢

热点阅读