开始正式学习C语言

C语言简介:

      BCPL->newB->C->UNIX->Minix->Linux->gcc

      C语言诞生于1970-1973年之间,在肯.汤普逊和丹尼斯.里奇的主导下编写完成,目前C语言归属于美国贝尔实验室

      C语言是专门为了编写操作系统而诞生的语言,所以天生适合硬件编程,以运行速度快而著称,也非常适合实现数据结

    构与算法。由于出现时间过早,C语言是存在非常多的缺陷。但前辈们总结了一些经验,可以用于避免大部分缺陷。(

    《C语言的陷阱与缺陷》C语言三剑客)

      C语言语法自由,也意味着危险(自由源于自律)

      C89语法标准,gcc默认的语法标准

      C99语法标准,是对C89的扩展和增强(gcc -std=gnu99)

      C11语法标准,全新的升级

第一个C程序

  #include<stdio.h>

      程序员所编写的代码并不是标准的C代码,需要一段程序把它翻译成标准的C代码,负责翻译的程序叫做预处理器,翻译的过

    程称为预处理,被翻译的的代码叫做预处理指令,以#开头的代码都是预处理指令

       #include 是把一个头文件导入到当前文件中

       #include<>中“<>”是指从系统指定的目录下导入头文件

       #include""中“""”先从当前路径下加载头文件,如果找不到,再从系统指定路径下加载头文件

       (操作系统是通过设置环境变量来指定加载头文件路径的)

       stdio.h  头文件:以.h结尾,里面存储的是一些辅助性代码,绝大部分是函数的声明

                源文件:以.c结尾,里面存储的是功能性代码

    (C语言标准委员会为C语言以函数的形式提供了一些基础功能,这些函数就被封装到libc.so

    库文件中,并用很多头文件负责对库中的函数进行分类说明,常用的有stdio.h、string.h...)

       stdio.h 负责对输入输出功能函数进行说明

  int main()

  {

      printf("Hello,world!\n");

      return 0;

  }

  main函数:

    C语言以函数为单位来管理代码,是管理代码的最小单位,一个函数就是一段具有某项功能的代码段

  main函数是程序执行的路口,有且只有一个

  int 是一种数据类型,它表示main函数的执行结果是一个整数

  return 功能有两个:1、结束函数的执行

                    2、返回一个数据给函数的调用者

    (main函数是由操作系统调用,它的返回值返回给操作系统,反映了程序是怎样结束的,通常有三种

    情况:

         正数     出现异常(别人的错误)

         0        一切正常

         负数     出现错误(自己的错误)

    可以通过 echo $? 命令来查看上一个程序的返回值

    printf/scanf 是标准库中的函数,负责输入、输出数据,用来调试代码

    printf("----------\n");

  转义字符:

    键盘上一些按键是没有符号的,用一些特殊的字符组合来表示,这些特殊的字符组合就是转义字符

  \n    换行

  \b    退一个字符

  \r    回到行首

  \t    制表符,用于对齐数据

  \a    铃响

  \\    表示一个“\”

  %%    表示一个“%”

  C语言以分号作为一行代码的结束,并使用大括号划分区域

编译器:

    负责把人能看懂的记录了代码的文本文件,翻译成计算机能看懂的二进制文件,由预处理器、编译

  器、链接器组成

    gcc是由GUN组织为了编译Linux内核代码而开发的一款免费、开源的编译器,默认采用C89标准,可用

  -std=gnu00设置语法为C99语法标准

    常用的参数:

         -E        显示预处理结果

         -c        只编译不链接

         -o        设置编译结果的名字  (gcc hello.c -ohello)

         -I        指定头文件的加载路径

         -S        生成汇编代码

         -l        指定要使用的库文件

         -Wall     以更严格的标准来检查代码,尽可能多地显示警告

         -Werror   把警告当错误处理

C代码变成可执行程序的过程

    1、预处理     把源文件翻译成预处理文件

          gcc -E code.c               显示预处理结果

          gcc -E code.c -o code.i     生成以.i结尾的预处理文件

    2、编译                           把预处理文件翻译成汇编文件

          gcc -S code.i 

    3、汇编 :                         把汇编文件翻译成二进制目标文件

          gcc -c code.s               生成以.o结尾的目标文件

    4、链接                           把若干个目标文件合并成一个可执行文件

          gcc a.o b.o c.o...          默认生成一个a.out的可执行文件

C语言文件类型:

     .h     头文件(头文件编译结果为.h.gch)

     .c     源文件

     .i     预处理文件

     .s     汇编文件

     .o     目标文件

     .a     静态库文件

     .so    共享库文件

数据类型:

   为什么要对数据进行分类:

      1.现实中的数据本来就自带类别属性

      2.对数据进行分类可以节约存储空间、提高运行速率

    存储空间的单位:

    Bit    比特 一个二进制位,只能存储0或者1,计算机存储数据的最小单位

    Byte   字节 八个二进制位,计算机存储数据的基本单位

    Kb     1024字节

    Mb     1024Kb

    Gb     1024Mb

    Tb     1024Gb

    Pb     1024Tb

  

  C语言中数据分为两大类:自建(程序员自己设计的:结构、联合、类)和内建(C语言自带的)

  内建中:(可使用sizeof运算符计算

     整型:有符号 signed                

                 signed char           1            -128~127

                 signed short          2            -32768~32767

                 signed int            4            正负20亿

                 signed long           4/8          

                 signed long long      8            正负9开头的19位整数

          无符号

                unsigned                

                unsigned char          1            0~255

                unsigned short         2            0~65536

                unsigned int           4       

                unsigned long          4/8

                unsigned long long     8            0~以1开头的20位整数

      注意:由于定义无符号数据 时比较麻烦,标准库把这些无符号的类型重新定义成了以下类型

        使用时需要包含头文件:stdint.h

      uint8_t  uint16_t  uint32_t  uint64_t

      int8_t   int16_t   int32_t   int64_t   

      size_t                          

      浮点型:

         float            4

         double           8

         long double      12/16

        注意:浮点数都是采用科学计数法存储的,二进制与整型数据之间需要进行换算,因此浮点

      浮点型数据耗时比整数型多得多,编程时应尽量选择整数型(小数点后六位有效)

      (time ./a.out 计算程序运行时间)

      模拟型:

        字符型char

             字符其实就是符号或图案,内存中存储的是整数,当需要显示成字符时会根据ASCII码

          表中对应的关系显示处相应的符号或图案

          '\0'  空字符,对应ASCII码为0

          '0'   48

          'A'   65

          'a'   97

        布尔型bool(先有了C语言之后才有了bool类型,所以C语言中是不可能有真正的布尔类型,C语

      言中用stdbool.h头文件对布尔类型进行了模拟)

变量与常量:

    变量:程序在运行期间数据可以变化的称为变量(相当于存储数据的盒子)

      定义方式:类型 变量名;  

          取名方式: 

                  1.由字母、字符、下划线组成

                  2.不能以数字开头

                  3.不能与32个C语言关键字重名

                    数据类型相关:

                      内建类型:void char short int long float double

                      自建类型:struct union enum sizeof

                      类型限定符:signed unsigned auto const static volatile register extern typedef

                    流程控制相关:

                      分支:if else switch case default

                      循环:while for do

                      跳转:break continue return goto

                  4.见名知意

      注意:变量的默认值是随机的,为了安全起见要对变量进行初始化,一般初始化为0

      

      变量的输入、输出:

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

              功能:输出数据

            format:"双引号包含的格式信息(提示信息+占位符)"

            ... : 变量列表

            返回值:输出字符的个数

            类型占位符:C语言通过类型占位符的方式来传递变量的类型

            整型:%hhd %hd %d %ld %lld     有符号

                 %hhu  %hu %u %lu %llu     无符号

            浮点型:

                %f %lf %LF

            字符型:

                %c %s

            

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

              功能:输入数据

            format: "双引号包含的格式信息(占位符)"

            ...: 变量地址列表 &变量名

            返回值:成功输入的变量个数

            注意:scanf需要的是变量的类型和地址(即 &+变量名 )

    

    常量:程序运行期间数值不能变化的称为常量

       100     默认int型

       100u    unsigned int

       100lu   unsigned long

       100llu  unsigned long long

       100l    long

       100ll   long long

       3.14    默认double

       3.14f   float

       3.14l   long double

       问题:100年有多少秒?

       #define SEC(3600*24*365*100u)

  带格式的输入输出

     %nd        显示n个字符宽度(不够则自动补空格,右对齐)

     %-nd       显示n个字符宽度(不够则自动补空格,左对齐)

     %0nd       显示n个字符宽度(不够则自动补0,右对齐)

     %n.mf      显示n个字符宽度(小数点算一位,不够则自动补空格,四舍五入保留小数点后m位)

     %g         不显示小数点后多余的0

  运算符

    自变运算符:++/-- 使变量的值自动+1或者-1

            前自变:++num/--num     立即有效

            后自变:num++/num--     在下一行语句生效

            注意:尽量不要在同一行内多次使用自变运算符

    算数运算符:+ - * / %

            整数/整数      结果为整数

            / %            除数不能为0(错误提示:浮点数例外,核心已转储)

    关系运算符:> < >= <= == !=

             比较的结果必须是0或者1,比较的结果还能继续参与运算

              int num=-5;

              if(1<num<10)   永远为真,运算规则与数学不一样(建议常量放左边)

    逻辑运算符:&& || !

       会先把运算对象转化成逻辑值,0转化为假,非0转为真

         A && B 全真为真

         A || B 有真即真

         !A    求反

        && 和 ||短路特性:当左边的运算对象已经能够确定整个表达式的运算结果时,右边的运算对象

      不再执行。

    三目运算符:运算对象有三个部分

       A?B:C   判断A的值是否为真,是的话执行B,不是则执行C

    (该语句不能使用流程控制语句,因为它必须要有运算结果)

    赋值运算符:

        a += b: a=a+b;

        a -= b;a=a-b

        a*=b

        a/=b

        ...

    位运算符:& | ~ >> <<

    

    sizeof 也是运算符,但是sizeof括号内的表达式不会计算

   类型转换:

      自动类型转换:只有相同类型的数据才能运算,不同类型的数据必须转换成相同的类型才能进行运算

         转换规则:1.以不丢失数据为基础,可以适当牺牲一些空间

                  2.字节少的向字节多的转

                  3.有符号的向无符号的转

                  4.整型向浮点型转

      

      强制类型转换:

        (新类型)数据: 有丢失数据的风险,慎重使用

  

  分支语句

    if(表达式)  //单分支

    {

      表达式为真时,执行此处语句。

    }

     if(表达式)  //双分支

    {

      表达式为真时,执行此处语句。

    }

    else

    {

      表达式为假时,执行此处代码

    }

    if(表达式)  //多分支

    {

      表达式为真时,执行此处语句。

    }

    else if(表达式2)

    {

      表达式2为真时,执行此处代码

    }

    ...

    else

    {

      表达式都为假时,执行此处代码

    }

    

    注意:大括号建议上下对齐,当大括号内语句只有一条时,大括号可以省略

开关语句

   switch(n)   //n可以时数值或表达式,但不可为小数

   {

     case val: ...    // val必须是整数常量

             break;

     case val: ...

          .

          .

      default: ...   // 如果所有的case都没有匹配成功,则打开该执行开关,并且放在任何位置都可以

                

   }

   注意:如果每个case后都有break,就形成了分支结构;switch不能与continue配合使用

   case a...b:可以表示一个范围,但是属于GUN专属语法不建议使用

  循环语句(让一段代码反复执行)

     for循环语句:(是一种比较灵活但是与其他循环相比具有一定危险性的一种循环)

     一般用一个变量来引导for循环的运行,即循环变量,一般为 i (index) 

     基本结构:

            for([1];[2];[3])

            {

              [4];

            }

        1.给循环变量赋初值,只有C99的标准才可以在此处定义循环变量

        2.判断循环条件,一般判断循环变量是否到达边界

        4.如果2为真则执行此处代码(此处也称为循环体)

        3.改变循环变量,防止出现死循环一般为(i++/i--)

    for循环的多种写法

    for(;;)

    {

      //死循环      

    }

    int i=0;

    for(;i<10;i++)

    {

    }

    for(i=0;i<10;)

    {

      i++;

    }

    while循环:

         while(条件)//当条件为真时执行循环体,为假时结束循环

         {

           ...

           //循环体

         }

        while循环相当于佛如循环的精简版本for(;条件;)

        for循环负责解决明确知道循环次数的问题

        while循环负责解决只知道结束条件,而不确定循环次数的问题

    do while 循环:

    do{

      //循环体

    }while(条件); //分号不能少

      先执行循环体,再判断循环条件是否为真(该循环至少执行一次)

      适合先干活,再检查的特殊情况  例如:密码问题

      问题:解释 for、while、do-while 有什么区别

    循环的嵌套:

     外层循环执行一次,内层循环执行n次






小练习:

     1;计算所有的水仙花数

     2:输入一个正整数,判断是否是素数

     3:输入一个正整数,判断是否为回文数

     4:输入一个六位密码,正确显示“登录成功”,错误提示“还剩几次机会”,错误超过三次显示“账号已锁定”

     5:输入一个整数分解显示

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值