Bootstrap

C语言-小知识点梳理

1、运算符中i++和++i的区别

当i=1时,

在j=i++;中是先用后加,就是(先用)先赋值j=i,那么j=1,然后(后加)再i=i+1,那么i=2;

在j=++i;中是先加后用,就是(先加)先i=i+1,那么i=2,然后(后用)再赋值j=i,那么j=2;

下面用例子说明一下:

例1:

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

运行结果如下:

2、()运算符

例2:

 

#include <stdio.h>
int main(void)
{
        int y=3,x=3,z=1;
        printf("%d,%d\n",(++x,y++),z+2);
        return 0;
}

运行结果如下:

括号里的(++x,y++),先执行++x,先加后用x=x+1,x=4,然后再执行y++,先用后加,输出的就是y值3和z+2的值就是3。

例3:

#include <stdio.h>
int main(void)
{
        int a;
        printf("%d\n",(a=3*5,a*4,a+5));
        return 0;
}

运行结果如下:

3、?:条件运算符

使用形式:表达式1?表达式2:表达式3 先判断表达式1,true执行表达式2,false执行表达式3

例4:
 

#include <stdio.h>
int main(void)
{
        int a=5,b=4,c=6,d;
        printf("%d\n",d=a>b?(a>c?a:c):(b));
        return 0;
}

运行结果如下:

先执行括号内的(a>c?a:c),a不大于c,反馈c=6,再比较a是否大于b,a>b就反馈(a>c?a:c)的值,输出就为6。

4、 运算符优先级及运算次序

例5:

#include <stdio.h>
int main(void)
{
        int a=-1,b=4,k;
        k=(++a<0)&&!(b--<0);
        printf("%d %d %d\n",k,a,b);
        return 0;
}

运行结果如下:

先执行(++a<0),先加后用,a=0不小于0(false),再执行!(b--<0),先用后减b=4,后减后b=3不小于0,再取逻辑非(false),最后k=false&&true,k输出0,所以以此输出k=0,a=0,b=4。

例6:

#include <stdio.h>
int main(void)
{
        int x=5,n=5;
        int m=5,y=2;
        int a=6,b=4,c=2;
        x+=n++;
        y+=y-=m*=y;
        printf("x=%d,n=%d\n",x,n);
        printf("y=%d\n",y);
        printf("!(a-b)+c-1&&y+c/2的值是%d\n",!(a-b)+c-1&&y+c/2);
        return 0;
}

运行结果如下:

先说x+=n++;,从右往左执行,先用后加,n=5,这个n是先用的,然后n=n++;,那么n=6(后加),把用的n代入x+=n中,x=10;所以输出,x=10,n=6;

然后y+=y-=m*=y;,应该先算m*=y,再算y-=m,最后算y+=y,得出y=-16;

最后!(a-b)+c-1&&y+c/2跟例5相似,就不重复了。

5、if语句的嵌套

if(表达式1)

        if(表达式2) 语句1;

        else 语句2;

那么其中的else究竟是与哪一个if相配对呢?在这里应该理解为:

if(表达式1)

{

        if(表达式2) 语句1;

        else 语句2;

}

如下例所示:

例7:

#include <stdio.h>
int main(void)
{
        int x=2,y=-1,z=2;
        if(x<y)
                if(y<0) z=0;
                else z+=1;
        printf("z=%d\n",z);
        return 0;
}

运行结果如下:

6、continue语句

continue语句的作用:结束本次循环,即跳过循环体下面尚未执行的语句,接着进行下一次是否执行循环的判断。

例8:

#include <stdio.h>
int main(void)
{
        int a,b;
        for(a=1,b=1;a<=100;a++)
        {
                if(b>=20) break;
                if(b%3==1)
                {
                        b+=3;
                        continue;
                }
                b-=5;
        }
        printf("a=%d\n",a);
        return 0;
}

运行结果如下:

先执行第一次循环b=1,然后判断b%3==1,再b+=3,然后结束循序进行下一次循环,一直循环,直到执行到第八次循环b=22,判断b>=20,然后退出for循环,打印循环次数a=8。

7、全局变量和局部变量

例9:

#include <stdio.h>
int a=3,b=4;
void fun(int x1,int x2)
{
        printf("%d,%d\n",x1+x2,b);
}
int main(void)
{
        int a=5,b=6;
        fun(a,b);
        return 0;
}

运行结果如下:

fun(a,b)函数里面的参数a和b是代入局部变量a=5,b=6,而函数fun(x1,x2)中printf("%d,%d\n",x1+x2,b);的b的值是表示全局变量b=4,所以输出的是局部变量a和b的和11,以及全局变量b=4。

 8、static声明局部静态变量

当希望函数中的局部变量在函数调用结束后依然存在,并在下一次调用函数时,该变量仍然保留上一次函数调用结束时的值,则可以将该变量的存储方式声明为static。

例10:

#include <stdio.h>
int f(int a)
{
        int b=0;
        static int c=3;
        b++;
        c++;
        return (a+b+c);
}
int main(void)
{
        int a=2,i;
        for(i=0;i<3;i++)
                printf("%4d",f(a));
        return 0;
}

运行结果如下:

9、宏定义

对程序中所有出现的“宏名”,都用宏定义中的字符串去代替。

例11:

#include <stdio.h>
#define ADD(x) x+x
int main(void)
{
        int m=1,n=2,k=3;
        int sum = ADD(m+n)*k;
        printf("sum = %d\n",sum);
        return 0;
}

运行结果如下:

把ADD(m+n)用宏定义中的字符串代替就是m+n+m+n,那么sum = ADD(m+n)*k;就是sum=m+n+m+n*k而不是sum=(m+n+m+n)*k,要切记!

例12:

#include <stdio.h>
#define FUDGE(y) 2.84+y
#define PR(a) printf("%d\n",(int)(a))
#define PRINT1(a) PR(a);putchar('\n')
int main(void)
{
        int x=2;
        PRINT1(FUDGE(5)*x);
        return 0;
}

运行结果如下:

10、strcat和strcpy的功能

strcat(str1,str2)把字符串str2接到str1后面;

strcpy(str1,str2)把str2指向的字符串拷贝到str1中去;

11,auto、register和extern变量

  • auto自动变量,属于动态存储方式,函数中定义的内部变量、形参和复合语句中定义的变量都属于自动变量。局部变量的默认存储方式为auto,以此关键字auto可以省略,auto不写则隐含定义为“自动存储方式”;
  • register寄存器变量,C语言允许局部变量的值存放在CPU内部的通用寄存器中;
  • extren声明外部变量,外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾结束。编译时将外部变量分配在静态存储区;有时需要用extern来声明外部变量,以拓展外部变量的作用域;

12、int*p(int)和int(*p)(int)的区别

  • int*p(int)是函数声明;
  • int(*p)(int)是函数指针;
;