嵌入式学习(三)

        由于非计算机专业毕业的,压根不知道该怎么学习编程。不妨把编程当数学来学。所以从下面几个方面来学习编程:常量、变量、运算、关系、命令。由于常量不变,没什么好学的。就从变量开始。

一、变量

【1】定义

定义方式:存储类型  数据类型  变量名;

        1)所谓“存储类型”,其实就像我们存钱一样,有专款专用的钱、有日常开销的钱、也有储备金。。。不同的存储类型,代表着不同的存储位置、不同的作用域。只有设定好了存储类型,计算机在你需要用的时候,才知道拿哪部分数据给你。C语言一般把存储类型为六大类:const static extern volatile auto register  auto 。在日常写代码的过程中存储类型auto 一般省略

        const:使用const定义的变量,在程序运行的该过程中值不能被修改

        static:定义静态变量

        extern:引入外部文件中的变量

        register:在寄存器中定义变量,不一定会申请成功

        volatile:防止代码优化,每一次都从内存中取变量的值

        auto:自动变量,不写存储类型局部变量默认是auto

        2)所谓的“数据类型”,如同我们平常的用钱的形式,例如:可以是支票、现金、余额宝等,都是钱。C语言的数据类型,主要有:整型、浮点型、字符型、数组、结构体、共用体、枚举型。

        3)所谓的“变量名”,其实就是标识符,如同人的名字。人没名字,对方就不知道你在呼唤他;变量如果没有名字,程序就不知道你需要调用谁。C语言对变量名是有一定要求的:

        a.可以由数字、字母和下划线构成

        b.不能以数字开头。例如,变量名不能为 1abcd

        c.严格区分大小写。例如,变量abcd1 与 abcD1 是两个不同变量

        d.不能和C语言的32个关键字重复。例如不能有以下这些关键字:

                数据类型相关的:int double float long short char struct union typedef enum

                存储类型相关的:const static extern register volatile auto

                结构相关的:for while do case switch if else goto

                辅助控制关键字:break continue default return

                其他关键字:sizeof

【2】变量的初始化和赋值

初始化,在定义的直接给初始值

赋值,先定义后赋值

使用变量前,一定要确保变量已经赋值过。例如:

        #include <stdio.h>                        

        int main(int argc, const char *argv[])

        {

           int a;    //定义了一个整形的变量a,没有初始化,存的是随机值

           printf("a=%d\n",a);  //错误。a没有初始值。但现在的编辑器一般认定为0

            int num = 10;  //定义了一个整形变量num初始化为10

            printf("num=%d\n",num);

            a = 100;  //给a赋值为100

            printf("a=%d\n",a);

            int num1 = num;  //使用已有的变量num给num1初始化

            printf("num1=%d\n",num1);

            num1 = a;  //使用已有的变量a给num1赋值

            printf("num1=%d\n",num1);

            int num1,num2,num3,num4;  //定义了四个整形变量num1、2、3、4       

            return 0;

        }

【3】类型转换

大的数据类型转小的数据类型是不安全的

小的数据类型转大的数据类型是安全的

i)隐式的强制类型转换

转换的过程是编译器做的,

#include <stdio.h>

int main(int argc, const char *argv[])

{

    char c = 'a';

    int num = c;  //隐式的强制类型转换,把c变量的ascii赋值给int类型的数据

    //char 1Byte    int 4Byte  小的数据类型向大的数据类型转换

    printf("%d\n",num);

    //signed定义有符号数  unsigned定义无符号数

    unsigned int num1 = 0xFFFFFFFF;  //给四个字节中的每个bit都置1

    //unsigned int num1 = 0xFF113478;

    //0b 1111 1111 0001 0001 0011 0100 0111 1000

    //把10行的num1转换成short=0x3478;

    //unsigned int num1 = 0x11111111;

    //unsigned char a = num1;

    printf("%u\n",num1); //4294967295

    unsigned short int num2 = num1;

    printf("%u\n",num2); //65535

    //int 4Byte  short 2Byte

    //大的数据类型向小的数据类型强转的时候,会发生数据的丢失,不安全的

    return 0;

}

ii)显式强转

格式:(强转的目标类型)强转的数据;

#include <stdio.h>

int main(int argc, const char *argv[])

{

    unsigned int num = 0xFFFFFFFF;

    unsigned short int num1 = (short)num;‘‘

    unsigned char a = (char)num;

    //显式的强制类型转换,可以看见强转的过程

    //把int类型的num强转为short类型

    //(强转的目标类型)强转的内容;  通常强转的结果会用对应的数据类型接收

    printf("%#X\n",a); //0xFF,输出一个字节

    printf("%#X\n",num1);  //0xFFFF

    return 0;

}

iii)有符号和无符号数之间的转换

隐式的强制类型转换,无符号数和有符号数一起运算,强转成无符号数

#include <stdio.h>

int main(int argc, const char *argv[])

{

    unsigned int c = 2;  //无符号数

    signed int a = -3;  //有符号数

    printf("%u\n",a+c); //隐式的强制类型转换,无符号数和有符号数一起运算,强转成无符号数

    if(a+c>0)

    {

    printf("1\n");

    }

    return 0;

}

【4】变量的取值范围

有符号数signed、无符号数unsigned

默认都是有符号数

根据数据的最高位是符号位,0表示是正数,1表示负数

原码、反码和补码

计算机中,数据都是以补码的形式进行存储和运算。

都是二进制表示的

原码:人能看懂的,十进制转换过来的

反码:原码和补码的一个中间状态 ,正数原码、反码和补码都一样,负数,原码的除符号位外其他位取反

补码:计算机中存储和运算用的都是补码,正数原码、反码和补码都一样,负数的补码是反码+1

正数的原反补都相同

负数的反码是原码除符号位外取反,补码是反码+1

有符号数    -123                      +123

原码1111 1011                        0111 1011

反码1000 0100                        0111 1011                         

补码1000 0101                        0111 1011

i)char    1Byte

无符号数[0,255]  ---- [0,2^8-1]

有符号数 [-2^7,2^7-1]

[0000 0000 ----- 0111 1111] ----- [0,2^7-1]

[1111 1111  ----- 1000 0000]  ------ [-2^7,0]

1000 0000  ------> 1111 1111 -----> 1 0000 0000  -0的补码  1000 0000  规定 1000 0000是-128的补码,-128没有原码和反码,-128补码的最高位,既是符号位也是数据位。

127  补 0111 1111 + 1  补码0000 0001    = 1000 0000

1    0000 0001

-1  1111  1111

0000 0001

1111  1111

0000  0000

计算机中数据存储的时候看的是数值(有无符号)

取出数据,看类型;

#include <stdio.h>

int main(int argc, const char *argv[])

{

    signed char c = 129;

    //存储看符号+

    //原码:1000 0001

    //反码:1000 0001

    //补码:1000 0001

    //取出看类型:

    //补码:1000 0001

    //反码:1000 0000

    //原码:1111 1111

    printf("%d\n",c);

    c = 255;

    //存储看符号+

    //原码:1111 1111

    //反码:1111 1111

    //补码:1111 1111

    //取出看类型

    //补码:1111 1111

    //反码:1111 1110

    //原码:1000 0001

    printf("%d\n",c);

    unsigned char p = -1;

    printf("%u\n",p);

c = 213;

    //存储看符号

    //原码:1101 0101

    //反码:1101 0101

    //补码:1101 0101

    //取出看类型

    //补码:1101 0101

    //反码:1101 0100

    //原码:1010 1011

    printf("%d\n",c);

    return 0;

}

ii)short 2Byte 16bit

无符号数[0,2^16-1]

有符号数 [-2^15,2^15-1]

正数[0,2^15-1]

负数[-2^15,0]

1000 0000 0000 0000

iii)int 4Byte  32bit

无符号数[0,2^32-1]

有符号数 [-2^31,2^31-1]

正数[0,2^31-1]

负数[-2^31,0]

1000 0000 0000 0000 0000 0000 0000 0000

补码是通过模运算得来的。

练习:

124,原码、反码和补码0111 1100

-35:1010 0011 -----> 1101 1100 ----->1101 1101

-126:1111 1110 -----> 1000 0001 ------> 1000 0010

-96:1110 0000 ----> 1001 1111 -----> 1010 0000

-24:1001 1000 ------> 1110 0111  ------> 1110 1000

-123:1111 1011 ------> 1000 0100 ------> 1000 0101

-115:1111 0011 ------> 1000 1100 ------> 1000 1101

二、标准输入输出函数

【1】printf

函数原型

int printf(const char *format, ...);

printf使用时,需要一个格式符和一个格式符对应类型的数据

printf("占位符/格式符",输出表象);  //有一个格式符就要有一个输出表象

printf("%d\n",10);  //10就是输出表象,%d就是10对应的格式符

printf("%c",'c');  //字符c时输出表象,%c是字符c对应的格式符

转义字符,就是有特殊意义的字符

\n:换行      10

\t:制表符    一个tab键的大小4个空格

\b:退格

\r:回车      回退到行首进行输出

\\:输出一个\,键盘上回车上面的\反斜杠,不是除号

格式符

%d:整形数据的格式符

%-nd:以n个数据宽度左对齐输出,不够就补空格

%nd:以n个数据宽度右对齐输出,不够就补空格

%ld:长整型数据的格式符

%f:浮点型的格式符,printf默认输出小数点后6位

%.mf:指定小数点后的输出位数

%lf:双精度浮点型的格式符

%c:字符型的格式符

%s:字符串的格式符

%#x:输出十六进制,并且带前导符0x,小写x,输出十六进制时对应的字母都是小写的

%#X:输出十六进制,并且带前导符0X,大写x,输出十六进制时对应的字母都是大写的

%%:  输出一个%

%u:无符号数输出的格式符

【2】sacnf

函数原型

int scanf(const char *format, ...);

scanf("格式符",变量的地址);

&:取地址符,取变量的地址

scanf以回车作为获取结束的标志,只有缓冲区内的数据>=格式符的个数回车是结束的标志

scanf从缓冲区内获取数据的标志,以空格、tab键和回车作为数据之间间隔的标志

ii)scanf在获取多个字符数据时,需要吸收垃圾字符

#include <stdio.h>

int main(int argc, const char *argv[])

{

    //scanf在连续获取多个字符类型数据的时候需要吸收垃圾字符

    //因为scanf作为数据分隔的标志,空格,tab和回车都是ascii中能查到的字符

    char a,b,c,d;

    int num;

    //1、利用scanf严格控制格式的特点,%c后面的空格起到吸收垃圾字符的作用

    //scanf("%c %c %c %c",&a,&b,&c,&d);

    //2、在格式符前面打空格,空格的作用是,吸收输入之前的所有垃圾字符

    /*scanf(" %c",&a);

  scanf(" %c",&b);

  scanf(" %c",&c);

  scanf(" %c",&d);*/

    //3、使用抑制字符 %*c

    //%*c一定要吸收掉一个字符不管字符是否是垃圾字符,不建议使用

    //scanf("%c%*c%c%*c%c%*c%c",&a,&b,&c,&d);

    //4、使用getchar吸收垃圾字符

    scanf("%c",&a);

    getchar();

    scanf("%c",&b);

    getchar();

    scanf("%c",&c);

    getchar();

    scanf("%c",&d);

    printf("a=%c\tb=%c\tc=%c\td=%c\n",a,b,c,d);

    return 0;

}

【3】字符的输入函数getchar()

getchar()从终端 获取单个字符

getchar();  //语句本身的结果就是从终端获取的字符

char c;

scanf("%c",&c); //通过scanf终端获取c

c=getchar();  //通过getchar终端获取c

【4】字符的输出函数 putchar()

输出单个字符

#include <stdio.h>

int main(int argc, const char *argv[])

{

    char c = 97;

    putchar(c);  //输出单个字符,不会换行

    putchar(10);  //输出换行

    putchar('1');

    return 0;

}

三、运算符

【1】算术运算符

运算符作用

+\-\*两数相加、相减、相乘

/如果左右两个操作数都是整形,就是取整运算,结果就是整形

只要有一个操作数是浮点型,结果就是浮点型,除数不能为0

%要求:两个操作数必须是整形,取余,除数不能为0

【2】自增自减运算符

a++,++a,a--,--a

int a = 10;  a++或者是a--表达式的结果仍然为10

++a,结果就是11

如果先看见运算符,结果就是运算后的值

如果先看见变量,结果就还是变量本身

练习:

1、使用带参宏实现,两数相乘*,两数相除/,两数模除%

#include <stdio.h>

#define M(a,b) a*b

#define D(a,b) (float)a/b

#define O(a,b) (int)a%(int)b

int main(int argc, const char *argv[])

{

    printf("%d\n",M(3,4));

    printf("%f\n",D(10,4));

    printf("%d\n",O(10.0,4.0));

    return 0;

}

【3】赋值运算符

=:赋值运算符

左值 = 右值;  把右值赋值给左值

左值,是既可以作为左值也可以作为右值的量

右值,只能作为右值的量

混合赋值运算符:

a+=1a=a+1

a-=1a=a-1

a*=1a=a*1

a/=2a=a/2

【4】关系运算符

非真即假,非0即1

0假,1真

在C语言中非0即为真

==判断左右两个操作数是否相等

!=不等于

a>b判断a是否大于b

a判断a是否小于b

a>=b判断a是否大于等于b

a<=b判断a是否小于等于b

练习:

1、终端输入两个数,判断两数是否相等

if(表达式成立)

{

执行代码块的内容;

}

2、终端输入一个三位数,输出该数个位+十位+百位的结果

3、终端输入一个四位数,输出该数个位、十位、百位和千位的结果

【5】逻辑运算符

逻辑运算的结果非0即1,非真即假

&&逻辑与,两个操作数都为真结果才是真,

有一个操作数为假结果就是假

||逻辑或,两个操作数都为假结果才是假

一个操作数为真结果就是真

!逻辑非,

逻辑短路现象

逻辑与运算,如果左侧表达式的值为假,右侧的表达式不会执行,逻辑与运算的结果为0/假

逻辑或运算,如果左侧表达式的值为真,右侧的表达式不会执行,逻辑与运算的结果为1/真

练习:

1、终端输入一个数,判断该数是否在区间[12,54]中。a>=12和a<=54同时成立

【6】条件运算符

C语言中的唯一一个三目运算符

表达式1?表达式2:表达式3

先执行表达式1,如果表达式1成立,执行表达式2,如果表达式1不成立,执行表达式3。

练习:

1、终端输入两个数,使用条件运算符,输出两个数中较大的数。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int num,num1;

    scanf("%d %d",&num,&num1);

num>num1?printf("%d\n",num):printf("%d\n",num1);

    return 0;

}

【7】逗号运算符

(表达式1,表达式2,表达式3·····表达式n)

每个表达式都会执行,取最右侧表达式的结果,

【8】位运算符

一般都使用无符号数进行位运算

对二进制进行运算的

  0000 1001 & 0000 1000 =0000 1000 = 8

  0000 1001 | 0000 1000  = 0000 1001  = 9

  0000 1001 ^ 0000 1000  = 0000 0001  = 1

~0000 1001 = 1111 0110  = 118

0000 1001>>3 = 0000 0001  = 1

0000 1001 << 4 = 1001 0000 = 144

练习:

1、求unsigned char类型数值0x1的数,<<3的结果。

如果没有特殊声明,bit从右向左从0开始,

2、有一个unsigned char类型的数据a,把他的第六个bit位置为1。

a|=(0x1<<6) <==> a = a | 0x1<<6

????    ????    |    0100 0000      0x1<< 6

?1??      ????

3、有一个unsigned char类型的数据a,把他的第六个bit位置为0。

a&=~(0x1<<6)

????  ????    &  1011 1111      ~(0x1<<6) 

?0??    ???? 

位运算常用于对数据的置位操作

    0与任何数都是0,1与任何数都是数本身

    1或任何数都是1,0或任何数都是数本身

    0异或任何数都是数本身,1异或任何数都是取反

已知unsigned char data;写出把data的第三位置1的表达式;

把data的第四位置0的表达式,讲data的第六位按位取反的表达式。^

data|=(0x1<<3);data&=~(0x<<4);data^=(0x1<<6)

#include <stdio.h>

int main(int argc, const char *argv[])

{

    unsigned char data = 0x76; //0111 0110

    //0111 0110  | 0000 1000  = 0x7E

    //0000 1000 = 0x<<3

    //第三位置1:0111 1110  0x7E

data|=(0x1<<3);

    printf("%#X\n",data);

    //0111 1110 & 1110 1111  = 0x6E

    //1110 1111 ~(0x1<<4)

    //第四位置0:0110 1110  0x6E

data&=~(0x1<<4);

    printf("%#X\n",data);

    //两数异或,同0异1

    //0异或任何数结果都是数本身,

    //1异或任何数都是对该位取反

    //0110 1110 ^ 0100 0000

    //0100 0000 = 0x1<<6;

    //第六位取反:0010 1110  0x2E

data^=(0x1<<6);

    printf("%#X\n",data);

    return 0;

}

【9】sizeof运算符

sizeof求数据的大小,单位是字节

sizeof(数据);  sizeof括号里面放什么,就求什么的大小。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    char c = '1';

    printf("%ld\n",sizeof(int));  //4

    printf("%ld\n",sizeof(short));  //2

    printf("%ld\n",sizeof('a'));  //4

    printf("%ld\n",sizeof(char)); //1

    printf("%ld\n",sizeof(c));

    return 0;

}

sizeof的结果64为默认是无符号长整型

32位默认是无符号整形

【10】运算符优先级

小知识:

    vim可以设置自动补全。方法如下

            在家目录下,cd .vim

            cd snippets

            vim c.snippets

            找到main的行,隐藏的使用l打开 ,添加内容,再保存退出

作业:

整理思维导图

有以下变量求输出结果

signed char c = 178;

printf("%d\n",c);

printf("%u\n",c);

unsigned char d = -9;

printf("%d\n",d);

printf("%u\n",d);

并写出数据存储和取出的过程

求-57的原码、反码和补码

-57的原码:1000 0000 0000 0000 0000 0000 0011 1001

反码:0x FF FF FF C6

补码:0x FF FF FF C7

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容