0%

初识C语言(三)

文章时效性提示

本文发布于 527 天前,部分信息可能已经改变,请注意甄别。

操作符

操作符之sizeof

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
int main() {
    int a = 10;
    int arr[] = {1,2,3,4,5,6};
    printf("%d\n",sizeof(a));//整型变量占内存4个字节
    printf("%d\n",sizeof a);//和上面的结果是一样的。
    printf("%d\n",sizeof(int));//整型变量占内存4个字节
    printf("%d\n",sizeof(arr));//计算数组的大小,单位是字节,4*6=24
    printf("%d\n",sizeof(arr)/sizeof(arr[0]));//想要知道数组元素个数,可以把数组占用字节大小/数组每个元素占的字节
    return 0;
}

sizeof(arr)/sizeof(arr[0])想要知道数组元素个数,可以把数组占用字节大小/数组每个元素占的字节。

操作符之前置后置++、--

后置++
1
2
3
4
5
6
7
#include <stdio.h>
int main() {
    int a = 10;
    int b = a++;//后置++,先使用a的值,然后a再自增
    printf("a = %d , b = %d",a,b);//a = 11 , b = 10
    return 0;
}

后置++,先使用a的值,然后a再自增。

前置++
1
2
3
4
5
6
7
#include <stdio.h>
int main() {
    int a = 10;
    int b = ++a;//前置++,先++,再使用,即a先自增,变成11,再把a的值赋给b
    printf("a = %d , b = %d",a,b);//a = 11 , b = 11
    return 0;
}

前置++,先++,再使用,即a先自增,变成11,再把a的值赋给b。

后置--
1
2
3
4
5
6
7
#include <stdio.h>
int main() {
    int a = 10;
    int b = a--;//后置--,先使用a的值,然后a再自减
    printf("a = %d , b = %d",a,b);//a = 9 , b = 10
    return 0;
}

后置--,先使用a的值,然后a再自减

前置--
1
2
3
4
5
6
7
#include <stdio.h>
int main() {
    int a = 10;
    int b = --a;//前置--,a先--,再使用
    printf("a = %d , b = %d",a,b);//a = 9 , b = 9
    return 0;
}

前置--,a先--,再使用

操作符之按位取反~

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main() {
    int a = 0;
    //4个字节,32个比特位
    //0的二进制序列:00000000 00000000 00000000 00000000
    int b = ~a;//b是有符号的整型,最高位表示的是符号位
    //取反后的二进制序列:1(符号位,1代表负数)1111111 11111111 11111111 11111111
    //~是按位取反的意思,位是二进制位。
    printf("%d\n",b);//使用时,打印的是二进制的原码
    //打印的结果是-1
    return 0;
}

原码、反码、补码:负数在内存中存储的时候,存储的是二进制的补码

操作符之(类型)强制类型转换

1
2
3
4
5
6
#include <stdio.h>
int main() {
    int a = (int)3.14;//原先3.14是double类型,想转换成int型
    printf("%d\n",a);
    return 0;
}

原先3.14是double类型,想转换成int型,打印的结果是3。
不建议在代码中使用

算数操作符

算数操作符包括+、-、*、/、%(求余数)

1
2
3
4
5
6
7
8
#include <stdio.h>
int main() {
    int a = 5/2;//结果是2。
    int b = 5%2;//结果是1。
    printf("%d\n",a);
  printf("%d\n",b);
    return 0;
}

移位操作符

移位操作符(移的是2进制位)  >>右移操作符、<<左移操作符

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
int main()
{
    int a = 1;
    //整型a占4个字节,32位,十进制是1,用2进制表示也就是 00000000 00000000 00000000 00000001
    int b = a<<1;
    //整型b是整型a左移1个字节的结果,也就是00000000 00000000 00000000 00000010,用十进制表示就是2
    printf("%d\n",b);
  printf("%d\n",a);//对a进行左移操作,a本身不变化。
    return 0;
//}

位操作符

位操作符,操作的是2进制位。 &(按位与) ^(按位异或) |(按位或)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int main()
{
    int a = 3;//a的二进制 0011
    int b = 5;//b的二进制 0101
    int c = a&b;
    //a和b按位与就是 0001,按位与也就是并且的意思,只有两个都是1,结果才是1,其余都是0。
    int d = a|b;
    //a和b按位或就是 0111,按位或就是有一个1结果就是1。
    int e = a^b;
    //a和b按位异或就是0110,按位异或就是:有1则1,全1则0。
    printf("%d\n",c);
    printf("%d\n",d);
    printf("%d\n",e);    
    return 0;
}

赋值和判断

赋值和判断:一个等号是赋值,两个等号是判断相等。

1
2
3
4
5
6
7
8
#include <stdio.h>
int main()
{
    int a = 10;
    a = 20;//赋值,两个==是判断相等
    a = a + 10;//也是赋值
    return 0;
}

单目操作符、双目操作符、三目操作符

>
>=
<
<=
 != 用于测试不相等
 == 用于测试 相等

1
2
3
4
5
6
7
8
#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    int c = a + b;//加号就是操作符,是双目操作符,就是左右有两个操作数
    return 0;
}

逻辑与操作符&&

1
2
3
4
5
6
7
8
#include <stdio.h>
int main() {
    int a = 3;
    int b = 5;
    int c = a && b;//a和b都不是0,所以都是真
    printf("%d\n",c);//a和b逻辑与的结果是1,因为逻辑与-全真则真,有假全假
    return 0;
}

a和b逻辑与的结果是1,因为逻辑与-全真则真,有假全假

逻辑或操作符||

1
2
3
4
5
6
7
8
int main()
{
    int a = 0;
    int b = 5;
    int c = a || b;//a是假,b是真
    printf("%d\n",c);//逻辑或操作符,有一个是真,结果就是真
    return 0;
}

逻辑或操作符,有一个是真,结果就是真

条件操作符(三目操作符)

exp1 ? exp2 : exp3;
exp代表表达式,上式的意思是,如果exp1的结果为真,exp2位最终结果,如果exp1的结果为假,exp3为最终结果

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main() {
    int a = 10;
    int b = 20;
    int max;
//    if (a>b)
//        max = a;
//    else
//        max = b;
    max = ( a > b ? a : b );//这个表达式和上面的if是一样的
    printf("%d\n",max);
    return 0;
}

常用关键字

break

break-用于停止循环

typedef-类型定义-类型重新定义

1
2
3
4
5
6
7
#include <stdio.h>
int main()
{
    unsigned int num1 = 20;//定义一个无符号呢整型num1
    typedef unsigned int u_int;//把unsigned int重定义成了u_int,就是别名
    u_int num2 = 20;//num1和num2两个变量的类型是一样的
}

typedef unsigned int u_int;unsigned int重定义成了u_int

auto

1
2
3
4
5
6
#include <stdio.h>
int main() {
    int a = 10;//局部变量-自动变量-在前面省略掉了auto
    //例如 auto int a = 10;
    return 0;
}

static 函数

static修饰函数,改变了函数的链接属性,普通函数有外部链接属性,被修饰后就没有了。

static修饰全局变量,改变了变量的作用域-让静态的全局变量只能在自己所在的文件内部使用,出了源文件就无法使用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
void test()
{
    static int a = 1;
    a++;
    printf("a = %d\n",a);
}

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

a是静态的局部变量,被static修饰,局部变量的生命周期延长了。
输出的结果是:

1
2
3
4
5
a = 2
a = 3
a = 4
a = 5
a = 6

相当于static int a = 1;只运行了一次?

extern - 用于声明外部符号

main.c

1
2
3
4
5
6
7
#include <stdio.h>
int main()
{
    extern int g_val;//声明外部符号
    printf("g_val = %d\n",g_val);
    return 0;
}

extern.c

1
int g_val = 100;//全局变量

打印的结果是 g_val = 100

extern声明外部函数
main.c

1
2
3
4
5
6
7
8
9
extern int Add(int,int);
int main()
{
  int a = 10;
    int b = 20;
    int sum = Add(a,b);
    printf("sum = %d\n",sum);
    return 0;
}

Add.c

1
2
3
4
5
int Add(int x,int y)
{
    int z = x + y;
    return z;
}

打印的结果是sum = 30

define定义常量和宏

define定义标识符常量

1
2
3
4
5
6
7
#include <stdio.h>
#define MAX 1000
int main() {
//  int a = 100;
    int a = MAX;//和上面的效果一样
    return 0;
}

define定义宏

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
//宏的定义
#define MAX(X,Y) (X>Y?X:Y)
int main()
{
    int a = 10;
    int b = 20;
    int max = MAX(a,b);
    printf("max = %d\n",max);
}

指针

指针变量的大小:在32位平台占4个字节,在64位平台占8个字节。

1
2
3
4
5
6
7
8
9
10
int main() {
    int a = 10;
    int* p = &a;//取出a的地址
    //有一种变量是用来存放地址的,就是指针变量,类型是int*
    *p = 20;//*-解引用操作符,通过*p把a里面的值改成20
    printf("%p\n",&a);
    printf("%p\n",p);//和a的地址一样
    printf("a = %d\n",a);
    return 0;
}

有一种变量是用来存放地址的,就是指针变量。

1
2
3
4
5
6
7
8
#include <stdio.h>
int main()
{
    char ch = 'w';
    char* pc = &ch;
    *pc = 'a';//通过*pc把ch里面的值改成a
    printf("%c\n",ch);
}