C语言 day1 | 我的日常分享

C语言 day1

一、位数 字节

一字节即1byte
一位即1bit
1b == 1024bit      10.24程序猿节
1kb == 1024b
1M == 1024kb
1G == 1024M
1T == 1024G
···········

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
int main(int argc,char *argv[]){
printf("sizeof(char)=%d\n",sizeof(char));
printf("sizeof(short)=%d\n",sizeof(short));
printf("sizeof(int)=%d\n",sizeof(int));
printf("sizeof(long)=%d\n",sizeof(long));
printf("sizeof(float)=%d\n",sizeof(float));
printf("sizeof(double)=%d\n",sizeof(double));
return 0;
}

——————32位平台—————–
char 字符类型 占1字节的空间(8位二进制位)
short 短整型 占2字节的空间(16位二进制位)
int 整型 占4字节的空间(32位二进制位)
long 长整型 占4字节的空间(32位二进制位)
float 单精度浮点型 占4字节的空间(32位二进制位)
double 双精度浮点型 占8字节的空间(64位二进制位)
——————64位平台—————–
char 字符类型 占1字节的空间(8位二进制位)
short 短整型 占2字节的空间(16位二进制位)
int 整型 占4字节的空间(32位二进制位)
long 长整型 占8字节的空间(32位二进制位)[与32位平台的差别]
float 单精度浮点型 占4字节的空间(32位二进制位)
double 双精度浮点型 占8字节的空间(64位二进制位)

二、 siged 与 unsigned

  1. signed(一般省略)
    二进制最高位为符号位,其他位为数据位;其中1表示负数,0表示正数。

  2. unsigned(不能省略)
    数据没有符号位,所有位数都是数据位。
    比如:unsigned char 范围0000 0000 ~ 1111 1111

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include<stdio.h>
    int main(int argc,char *argv[]){
    // 定义一个有符号的int
    signed int num1 = 10;//num1是有符号的int

    // signed 默认是省略的(推荐)
    int num2 = 10;//num2也是有符号的int

    // 定义无符号的int,unsigned不能省略
    unsigned int num3 = 10;

    return 0;
    }
  3. 输出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include<stdio.h>
    int main(int argc,char *argv[]){
    // 有符号int数据输出
    int num1 = 0;
    printf("%d\n",num1);

    // 无符号int数据输出
    unsigned int num2 = 0;
    printf("%u\n",num2);

    // 有符号long数据输出
    long num3 = 0;
    printf("%ld\n",num3);

    // 无符号long数据输出
    long num4 = 0;
    printf("%lu\n",num4);

    // 有符号short数据输出
    long num5 = 0;
    printf("%hd\n",num5);

    // 无符号short数据输出
    long num6 = 0;
    printf("%hu\n",num6);

    return 0;
    }
  4. 输入
    与输出类似

三、进制

四、register sizeof typedef volatile

  1. register
    1
    2
    3
    4
    #include<stdio.h>
    int main(int argc,char *argv[]){
    register int num;
    }
  • 尽量把num放到寄存器中,寄存器可能满了,放不下。
  • 如果没有标明register,如果num被高频繁使用,系统也会将其放到寄存器中
  • 注意:寄存器的变量不能对其取地址&num,只有在内存中的变量才有地址
  1. sizeof()
    输出数据类型所占的字节数

  2. typedef
    给已有的类型取一个别称

步骤:

  1. 用已有的类型 定义一个变量
  2. 用别名 替换 变量名
  3. 在整个表达式的前方加上typedef

千万不要认为简单就不按步骤走;不要以为一个typedef后面第一个是已有类型 第二个是起的别名,旧的在中间,新的在后面。看看案例2就了解了

案例1:

1
2
3
4
5
6
// 1、
int num;
// 2、
int INT32;
// 3、
typedef int INT32;

案例2:给int arr[5] 取个别名

1
2
3
4
5
6
7
8
9
10
    typedef int arr[5] ARR // × 大错特错了

// 1、
int arr[5];
// 2、
int ARR[5];
// 3、
typedef int ARR[5];
// 使用 用ARR去定义变量
ARR arr;//arr就是一个拥有5个int元素的数组
  1. volatile
    防止编译器优化 强制访问内存的操作
    编译器对访问该变量的代码就不再进行优化,系统总是重新从它所在的内存读取数据
    1
    2
    3
    4
    5
    #include<stdio.h>
    int main(int argc,char *argv[]){
    volatile int i=10
    return 0;
    }
    比如,现在有个有害气体检测装置,他检测到有害的气体的浓度,后通过一定的方式,最后存到内存中,由于气体浓度检测要求是实时的,会被CPU高频次的访问,这个时候系统会干个好事,将存在内存中的气体浓度值放到寄存器中,这个时候CPU每次都会是在寄存器中访问了,这个时候就非常危险。如果放在寄存器时的那个时刻有害气体浓度只有5%,而后有害气体浓度到达了95%这个时候cpu还是从寄存器中读取出的5%,展示给我们人的也是5%,但是这个时候实际上有害气体浓度已经很高了,人会有生命危险。

五、实型数据 (float 与double的一些问题)

  1. 实型常量
    实型常量也称为实数或者浮点数
    十进制形式:由小数点或数字组成 0.0、0.31/4.0
    指数形式:123e3 表示123*10^3

不以f结尾的常量是double类型

1
2
3
4
5
6
#include<stdio.h>
int main(int argc,char *argv[]){
printf("%d",sizeof(3.14));//输出8
printf("%d",sizeof(3.14f));//输出4
return 0;
}

问题
float f = 3.14;有没有问题?

答:3.14为const double 赋给 float f,将一个八字节的数据赋给了四字节的数据,但对于这个细品又似乎没有问题,好比把一个能装八升水的瓶子里的水往只能装四升水的空瓶子的倒,但是能装吧升水的瓶子也有可能只装了一升水
赋值语句等号两边类型尽量匹配

六、字符与字符串

计算机是只能储存数字的,对于字符,先将其转换成对应的ASCII码值,再进行存储

1
2
3
4
5
#include<stdio.h>
int main(int argc,char *argv[]){
char ch = 'a';
return 0;
}

过程分析:计算机先去找a对应的ASCII码值为97在赋给ch;’a’中的单引号’’是取字符的ASCII码。
char ch = 'a';char ch = 97;完全等效

思考:下面现象是为什么?

1
2
3
4
5
6
7
8
9
#include<stdio.h>
int main(int argc,char *argv[]){
char ch = 'a';
printf("%d",sizeof('a'));//4字节
printf("%d",sizeof(char));//1字节
printf("%d",sizeof(ch));//1字节

return 0;
}

答:单引号’’是取字符的ASCII码值,第一个printf本质上是测常量97的字节数;而第二个printf测的是char类型,第三个printf测的是char类型的变量。

案例:实现键盘输入abc,然后输出字符ac。
答:先来了解一下原理,当从键盘输入abc后,按下回车键Enter后键盘输入的abc会到标准输入设备,说人话就是一个用来缓冲的内存,当执行ch1=getchar()时,系统会把缓冲内存的第一个字符a拿出来给内存中的ch1;如果执行getchar(),同样的系统会把缓冲区内存中的第二个字符b取到,getchar()的本质就是去缓冲区拿一个字符,由于没有赋给任何变量,没有人要,那我给谁呢,系统索性就把取到的字符给扔掉了,丢弃一个字符。
图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
int main(int argc,char *argv[]){
char ch1='\0',ch2='\0';
printf("请输入abc:");

ch1=getchar();//取到a
getchar();//丢弃一个字符b
ch2=getchar();//取到c

printf("ch1=%c\n",ch1);
printf("ch2=%c\n",ch2);

return 0;
}
  1. 转义字符
    ‘\n’换行
    ‘\t’缩进
    ‘\\‘表示一个斜杠’'
    ‘%%’表示一个百分号’%’

问题:下面四项哪两个是相等的?
A: printf("%d",'0');
B: printf("%d",'\0');
C: printf("%d",0);
D: printf("%d","0");
答案:BC

其实看他们中哪两个相等,其实就是去判断他们中哪两个在计算机中储存的二进制相同A:字符’0’的ASCII码值为48;B:转义字符’\0’表示的就是0;C:0就是0,不用多说了;D:字符串”0”,表示字符串”0”的第0个元素的地址。

  1. 字符串 ""
    1
    2
    3
    4
    5
    6
    7
    8
    #include<stdio.h>
    int main(int argc,char *argv[]){

    printf("%s\n","hello");
    printf("%d\n",sizeof("hello"));//打印6

    return 0;
    }
    思考一下:上面hello只有五个字符,hello所占的字节数为什么是6?
    原因就是:系统会给每个字符串的末尾自动添加一个结束符’\0’来让计算机知道,什么时候该结束打印;字符串是第0个元素的首地址,打印的时候会一次从第0个元素往后打印知道碰到’\0’时结束打印。我们可以用如下代码来进行验证。
  • 单引号取得是字符的ASCII码值
  • 双引号取得是字符串首元素的地址
  • %s从字符串的首元素逐个输出字符,直到遇到’\0’结束
1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int main(int argc,char *argv[]){

printf("%s\n","hello world");//打印hello world
printf("%s\n","hello\0 world");//打印hello
printf("##%s###\n","\0hello\0 world");//什么都没有
printf("%d\n",sizeof("hello world"));//打印12
printf("%d\n",sizeof("hello\0 world"));//打印13

return 0;
}

思考:’a’与”a”有什么区别?

二、格式化输出

%d 十进制有符号整数    %u 十进制无符号整数
%x 以十六进制表示整数    %0 以八进制表示整数
%f float性浮点数    %lf double型浮点数
%e指数形式的浮点数    %s 字符串
%c 单个字符    %p 指针的值

特殊应用:
%3d
%03d 不足补0
%-3d 左对齐
%5.2
注意:%-03d 千万不要这样写