【C语言初阶】C语言入门——第一讲

简介: 本篇主要介绍了一些C语言的基础知识,如何编写一个C程序、数据类型、常量、变量、字符串、转义字符等,专为C语言的初学者所准备

一:什么是c语言?

1.1:什么是计算机编程语言?

c语言是一种计算机编程语言。那么,很多小伙伴可能又要问了:“那计算机编程语言又是什呢?”别急,听我慢慢来告诉你。我们人和人之间的交流需要通过语言,于是世界上就诞生了许多种人们用来交流的语言,比如汉语、英语、法语等等。那么人们发明计算机编程语言也一定是为了用来交流的。说到这里,想必许多聪明的小伙伴已经猜出来了什么是计算机编程语言了。没错,计算机编程语言就是人们用来和计算机交流的一种语言。你想想,一个老外,假如他只会英语,那你用汉语和他交流他一定是听不懂的。计算机也一样,它只能听得懂计算机编程语言,想要和计算机交流,那我们就必须得用计算机编程语言。当前人们发明了成千上万种计算机语言,常见的有:C,C++,Java,Python等等。

1.2:C语言的应用场景

广泛应用于底层开发。C语言的设计目标是提供一种能以简易 的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的 C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超 级电脑等作业平台。

1.3:C语言的小历史

二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制 定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。目前2011年12月8 日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标 准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉 字编程。

1.4:C语言的编译器

主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。其中Clang由苹果公司研发,GCC主要应用在Linux平台上,我们比较常用的是MSVC,VS家族就和它有着密不可分的联系。这里多说一点,向我自己比较常用的就是vs2019,实际上是一个集成开发环境,它集成了多种功能,比如编辑器(用来写代码的)、编译器、链接器、调试器等。

二:如何写第一个C语言程序?

第一步:创建一个项目

我们需要准备一个上面提到过的集成开发环境,这里以vs2019为例。首先我们需要用vs2019来创建一个项目,具体步骤如下图:

打开vs2019就会出现下面这张图,我们选择“创建新项目”

image.gif编辑

接着会出现下面这个界面,这里注意,虽然我们要写的是C语言代码,但是这里选择"C++"就可以,然后选择"空项目",这两项选择完以后,点击下一步。

image.gif编辑

接着会出现这个界面。大家切记!!!项目名称一定要取一个有意义的,千万不要随便写,还要尽量避免中文。一般这个项目名要起到提示我们的作用,即使我们在很久以后看见这个项目名称,也能见其名知其意,很快想起来里面存的是什么代码。位置也不要用系统默认的存储地址,这样很不方便我们以后查找自己之前写过的代码,我们可以建一个专门的文件夹,点击“位置”后面的三个小点,选中我们建立的这个文件夹,这样一来,我们写的代码就会被存进这个文件夹,后面找起来会方便很多。

image.gif编辑

这样一来,我们的第一步创建一个项目就顺利完成啦。

第二步:创建源文件

选择源文件

image.gif编辑

右击鼠标,然后选择“添加”->“新建项”

image.gif编辑

接着出现下图,我们选择“C++”文件(写C或者是C++都选他就可以),然后取一个名称以.c为后缀,如果是C++程序,则以.cpp为后缀。

image.gif编辑

到此,我们的第二步创建源文件也已经大功告成。

第三步:写代码

终于到了最激动人心的时候了,我们可以开始写代码了。

int main()
{
  return 0;
}

image.gif

这段代码就是C代码的基础构架,这里需要提醒几点:

1、main叫做主函数

2、主函数是程序的入口

3、C语言代码中必须有主函数

4、但是有且仅有一个主函数

5、一个工程(项目)中可以有多个.c文件,但是多个.c文件中只能有一个main函数


#include <stdio.h> //包含输入,输出函数的头文件
int main()
{
  printf("hello word");  //printf是专门用来在屏幕上打印数据的,是C语言标准库中提供的一个库函数
  return 0;
}

image.gif

此段代码的运行结果是:

image.gif编辑


除了上面介绍的主函数写法外,主函数还有其他的几种写法,代码如下:

int main(int argc, char* argv[])
{
     return 0;
}

image.gif

int main(void)//   void写到这里表示main函数不需要参数
{
  return 0;
}

image.gif

void main()
{
  printf("hehe\n");
}

image.gif

值得注意的是,最后一种方法已经非常老套了,几乎没有什么人用了


到这里,经过上面的三个步骤,我们已经能够写一个非常简单的C语言程序了

三:数据类型

在日常生活中,我们会用到整数,小数,字母等等。在 C 语言中,它们属于不同类型的量,数据类型就是用于声明不同类型的变量或函数的一个系统。变量的类型决定了变量存储占用的空间。下面是一些常见的数据类型:

char        //字符数据类型
short       //短整型
int         //整形
long        //长整型
long long   //更长的整形
float       //单精度浮点数
double      //双精度浮点数

image.gif

在vs2019中,这些不同的类型,系统分配给他们的存储空间是不同的,我们可以通过sizeof函数测得,具体情况如下:

image.gif编辑

需要注意的是:sizeof测得的数字单位是字节(Byte)。 它是是计算机信息技术用于计量存储容量的一种计量单位。这样的计量单位还有(按照从小到大的顺序排):bit、Byte、KB、MB、GB、TB、PB。他们的换算关系是:1Byte=8bit,1KB=1024Byte,1MB=1024KB,1GB=1024MB,1TB=1024GB。看了上图代码,可能会有同学产生疑问:为什么长整型long和整型int分配到的字节数都是4?这是因为C语言中仅要求了长整型的字节不能小于整型的字节就行,可以等于。

不同的数据类型还对应着不同的格式输出符,如下:

char       %c //字符数据类型
short      %d//短整型
int        %d//整形
long       %d//长整型
long long  %d//更长的整形
float      %f//单精度浮点数
double     %lf//双精度浮点数

image.gif

四:变量、常量

生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)。有些值是可变的(比如:年龄,体重,薪资)。 不变的值,C语言中用常量的概念来表示,变得值C语言中用变量来表示。

4.1:定义变量的方法

int age = 150;
float weight = 45.5f; //此时是float型,如果没有f则是double型
char ch = 'w';

image.gif

值得注意的是,我们在创建变量的同时需要给一个初始值!

int a;    //这不是好习惯
int a=0;  //这才是正确做法

image.gif

4.2:变量的命名

    • 只能由字母(包括大写和小写)、数字、下划线(_)组成。
    • 不能以数字开头
    • 变量名不能用关键字
    • 长度不能超过63个字符
    • 区分大小写
    int A=0;
    int a=1;//这里定义了两个不同的变量A=0和a=1

    image.gif

    4.3:变量的分类

      • 局部变量
      • 全局变量
      int a = 10;//全局变量
      int main()
      {
        int b = 20;//局部变量
        return 0;
      }
      int c = 100;//全局变量

      image.gif

      上面代码中的,a和c,都是一个全局变量,可以看出来他们都有一个共同的特点——都在主函数外面。b是一个局部变量,他在主函数里面。区分局部变量和全局变量的详细方法就不在这里赘述了,随着进一步的学习,我会分享给大家。


      int a = 1;
      int main()
      {
        int a = 0;
        printf("%d", a);
        return 0;
      }

      image.gif

      大家看下上面这段代码,可以发现在这段代码中,主函数的里面和外面都定义了变量a,这时我们可能就会疑惑了,此时的a到底是多少呢?是1还是0呢?先卖个关子,大家可以先猜一下。别急,我们来实践出真知,请看此段代码的运行结果:

      image.gif编辑

      运行结果是0,你有没有猜对呢。由此可见,当局部变量和全局变量名字冲突的时,局部变量优先。但这里还是要提醒大家,尽量避免冲突。


      下面给大家展示一下变量的使用

      #include <stdio.h>
      int main()
      {
          int num1 = 0;
          int num2 = 0;
          int sum = 0;
          printf("输入两个操作数:>");
          scanf("%d %d", &num1, &num2);
          sum = num1 + num2;
          printf("sum = %d\n", sum);
          return 0;
      }

      image.gif

      这段代码希望实现的是,用户从键盘上输入两个数字后得到这两个数字的和。这里的scanf是一个库函数可以从键盘接收数据。这里定义了三个变量,分别是num1、num2、sum,num1和num2分别用来储存从键盘上输入的两个数子,sum则是用来储存这两个数字的和。在从键盘上输入数字时需要注意两个数字之间要用空格隔开,如下图输入框中1和2之间有一个空格。

      image.gif编辑

      代码的运行结果是:sum=3。

      image.gif编辑

      4.4变量的作用域和生命周期

      作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效和可用 的而限定这个名字的可用性的代码范围就是这个名字的作用域。

      4.4.1:局部变量的作用域

      局部变量的作用域是变量所在的局部范围。大家看下面这段代码:

      #include <stdio.h>
      int main()
      {
        {
          int a = 5;
        }
        printf("%d", a);
        return 0;
      }

      image.gif

      这里用了一对大括号把 int  a  =  5;这条语句括了起来,然后调用了printf函数,希望将a的值打印出来,能不能成功呢?

      image.gif编辑

      很明显,在编译的时候报错了,提示我们没有对a进行声明和定义。此时大家可能就会纳闷了,我不是已经定义了a=5嘛,为什么还会这样。其实,这就是变量作用域搞的鬼。在这里一个大括号就是一个代码块, a的作用域就被限制在了大括号里,只有在大括号里a的值才等于5,出了这个大括号a就不再等于5了。

      4.4.2:全局变量的作用域

      全局变量的作用域是整个工程。

      image.gif编辑

      此时在主函数中打印a的值,结果为5。


      我们还可以通过extern来声明一个外部符号,如下图:

      image.gif编辑

      在同一个工程里我分别创建了“text.c”文件和“add.c”文件,在“add.c”里定义了一个变量a=5,如果我们想在“text.c”这个文件中用这个变量a,那只需要用extern将a声明一下即可,此时a也是全局变量。

      4.4.3:变量的生命周期

      变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。变量的生命周期和变量的作用域息息相关,在进入作用域时创建变量,向操作系统申请相应的字节来存储变量,出作用域时销毁,即就是把存储空间(前面申请来的字节)还给操作系统。

        • 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
        • 全局变量的生命周期是:整个程序的生命周期。

        4.5:常量

        常量可分为以下四大类:

          1. 字面常量
          2. const修饰的常变量
          3. #define定义的标识符常量
          4. 枚举常量

          下面逐一为大家介绍:

          字面常量

          int main()
          {
            1;   //数字常量
            2;   //数字常量
            3.14;   //数字常量
            'a';  //字符常量 
            'c';  //字符常量
            "abcde";  //字符串常量
            return 0;
          }

          image.gif

          这里需要注意的是字符常量要用一对单引号('  ')引起来,字符串常量要用一对双引号(" ")引起来。


          const修饰的常变量

          image.gif编辑

          可以看到代码的第9行报错了,它提示我们表达式必须是可修改的左值,这就意味着此时的a是一个等于5的常量,后面不能对a重新修改赋值。但常变量,它的本质其实还是一个变量,证明如下:

          image.gif编辑

          箭头指向的是一条定义数组的语句,先大概介绍一下数组,数组就是向操作系统申请一块连续的存储空间用来存储多个相同类型的数据,如上图,[ ]里的数字代表的是数组长度,就是说这个数组可存多少个int型数据,后面的{0}是对数组进行初始化,大家先知道即可,后面会细讲。上图[ ]里面是a,我们本意是希望这个数组的长度为5,可以存储5个数据,但运行的时候程序却报错了提示我们[ ]里必须是一个常量值,这也就意味着这里的a其实是一个变量。由此可见,虽然我们定义了一个常变量a=5,但这个a本质上还是一个变量,这一点大家一定要注意!


          #define定义的标识符常量

          image.gif编辑

          还是上面的证明方法,首先我们用#define定义一个标识符常量M,让它等于10,此时我们让[ ]里是M,希望得到一个长度为10的数组,此时的代码编译顺利通过了。 可见这里的M是一个货真价实的常量。


          枚举常量

          枚举的意思就是一一列举,比如我们可以将所有的血型一一列举出来,可以将三原色一一列举出来等等,这些都叫枚举。

          image.gif编辑

          上图的代码,定义了一个枚举类型,它的可能取值是RED,GREEN,BLUE,在主函数中把他们依次打印出来结果是0,1,2。枚举常量的取值是从0开始依次增加的整数。

          image.gif编辑

          上图代码的15行希望对RED重新赋值成100,但编译的时候却报错了提示我们表达式必须是可修改的左值,因此这里的枚举常量RED也是一个实实在在的常量,不可以对其重新赋值。


          4.6:声明和定义

          int a;
          int b=5;

          image.gif

          其中第一条语句声明了一个整型变量(int型)a,第二条语句则是定义了一个整型变量b,它等于5。声明仅仅是告诉编译器我这里有一个整型变量,它的名字是a。定义则是比声明多了一个赋值,比如我们定义b=5,此时编译器给b分配了4个字节的存储空间。下面以具体的例子来看看声明和定义的区别。

          image.gif编辑

          上面这段代码在最后一行定义了a=5;希望在主函数中将a的值打印出来,但编译的时候出了问题,它提示我们‘a’是未声明的标识符。原因是当代码执行到22行的时候,它并不知道a是什么,在此之前并没有对a进行任何的声名或者定义。怎么解决呢?看下图代码:

          image.gif编辑

          可见只要在最开始添加一条声明语句,告诉编译器这里有一个整型变量a,最后就可以把a正常输出了。


          五:字符串+转义字符+注释

          5.1:字符串

          "abcde"

          image.gif

          这种由双引号引起来的一串字符称为字符串字面值简称字符串。 需要注意的是:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。

          image.gif编辑

          上图代码中定义了两个不同的字符串,分别是ch1和ch2,对它俩用了不同的初始化方法(注:[ ]为空也就是没有规定数组的长度,其真实长度会根据后面{ }中的初始化自行决定),其中ch1是一个字符一个字符进行初始化 ,通过监视窗口可以看出来ch1数组中只有3个字符'a','b','c'。对ch2则是用字符串进行初始化,通过监视窗口可以看出来ch2数组中有4个字符'a','b','c','\0'。再看看对这两个数组进行打印会有什么结果:

          image.gif编辑

          为什么ch1打印出来会是这种情况呢?原因是'\0'是字符串结束的标志,ch1数组在初始化时是一个字符一个字符进行的,并且我们没有把'\0'也放进ch1数组中,这就导致在打印ch1的时候,编译器会从a开始一直往后打印,知道出现'\0'位置。那么就会有人问了,'\0'究竟什么时候出现呢,这我还真没法回答你。在同一台电脑上运行n次这段代码,可能会出现n种不同的结果。当我们在初始化ch1的时候加上'\0',打印出来的结果就正常了:

          image.gif编辑

          接下来我们再来求一下字符串长度,C语言提供了一个库函数strlen,可以计算字符串的长度,统计的是'\0'之前字符的个数。用这个函数得调用#include <string.h>这个头文件。

          image.gif编辑

          通过代码的执行结果我们可以看出来这两个字符数组的长度都是3。


          5.2:转义字符

          转义字符顾名思义就是转变意思。下表是一些常见的转义字符。

          image.gif编辑

          image.gif编辑

          image.gif编辑这里重点介绍一下'\ddd'和'\xdd',先上代码:

          image.gif编辑

          第30行的语句是希望用%c的格式打印出转义字符'\101',那为什么最后的执行结果是A呢?首先我们要知道'\ddd'这个转义字符,转义后代表什么意思,它转后的字符值是与该八进制数字对应的ASCII字符(由于计算机的工作基于二进制也就是以0或1来表示,但是字符不便于计算机工作,因此人们就想了一个办法,那就是让每一个字符都对应一个数字,这样就方便计算机工作,因此就诞生了ASCII)。回到正题,根据前面提到的,那这里的'\101'就意味着与101这个八进制数字对应的ASCII字符,因为每个字符对应的ASCII代码都是十进制,所以我们先要把八进制下的101转化成十进制数字,转化后的结果是65,查ASCII表可以得知65对应的字符是A,所以打印结果是A。需要注意,这里的八进制数字和十六进制数字都不能太大,因为ASCII代码有范围限制,超出这个范围程序就会出错。别看一个转义字符都是由两个甚至多个字符组合而成就比如'\n'由'\','n',2个字符共同组成,但实际上'\n'就只代表一个字符,其实我们可以从两个方面看出之一点,首先就是它们的名字,它们叫做转义字符,只有一个才能被叫做字符,多个那就叫字符串了,其次我们也可以通过代码中对其的引用看出来,我们在引用这些转义字符的时候都用的是单引号(' '),这些都从侧面反映了转义字符在算字符数量的时候只代表一个。但也会出现陷阱,那就是,如果'\ddd'中ddd表示的八进制数字对应的十进制和'\xdd'中dd表示的十六进制数字对应的十进制超过ASCII代码的范围。此时代码编译时就会出错,如下图:字符串"c:\test\622\test.c"中'\622'其中八进制数字622对应的十进制是402,此时的402已经远远超过了ASCII代码的范围了,没有任何一个字符的ASCIID代码是402。

          image.gif编辑

           还有一个陷阱那就是八进制数字中不能有超过大于等于8的,下面代码展示的字符串中\628,由于八进制数字中不可能存在比7大的数,所以这里的'\62'算一个转义字符,'8'算一个字符。这样数下来这个字符串的长度就是14。

          image.gif编辑

          5.3:注释

            • 代码中有不需要的代码可以直接删除,也可以注释掉。
            • 代码中有些代码比较难懂,可以加一下注释文字

            具体方法主要有以下两种:

            /*你最棒*/
            //那最棒

            image.gif

            /**/是将/*中间的内容注释掉,而//则是把//这一行//后面的所有内容注释掉。

            六:选择语句

            image.gif编辑

            上图代码展示的就是一个最常见的if  else 选择语句,它的意思是如果从键盘输入的值大于10则执打印出“好好学习”,如果输入的值小于3,则打印“天天向上”,如果大于等于3小于等于10则打印“万事顺意”。可见选择结构只会选择其中的一种情况去执行。可以有多个else if。

            七:循环语句

              • while语句
              • for语句
              • do...while语句

              image.gif编辑上面代码展示的是一个while循环,当a<10的时候就打印“万事顺利”,然后利用a++;这条语句对a+1,直到a=10为止不再打印。

              目录
              相关文章
              |
              2月前
              |
              安全 编译器 C语言
              C++入门1——从C语言到C++的过渡
              C++入门1——从C语言到C++的过渡
              69 2
              |
              18天前
              |
              存储 NoSQL 编译器
              【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
              指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
              72 3
              【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
              |
              6月前
              |
              C语言
              C语言初阶:如何判断是否为素数并且输出
              C语言初阶:如何判断是否为素数并且输出
              49 0
              |
              2月前
              |
              存储 Java 编译器
              初识C语言1——C语言入门介绍
              初识C语言1——C语言入门介绍
              35 1
              |
              2月前
              |
              C语言
              回溯入门题,数据所有排列方式(c语言)
              回溯入门题,数据所有排列方式(c语言)
              |
              4月前
              |
              C语言
              C语言------程设设计入门
              这篇文章是C语言程序设计的入门教程,涵盖了C程序的实现过程、VC集成开发环境的使用、基本数据类型的使用、格式控制字符的作用,以及通过示例代码演示了如何使用printf()函数输出不同类型的数据。
              C语言------程设设计入门
              |
              5月前
              |
              存储 Java C语言
              【C语言入门】初识C语言:掌握编程的基石
              【C语言入门】初识C语言:掌握编程的基石
              72 4
              【C语言入门】初识C语言:掌握编程的基石
              |
              4月前
              |
              NoSQL Java 编译器
              C语言从入门到精通该怎样学?
              持续学习与实践:编程是一门需要不断学习和实践的技能,要保持对新技术和新知识的敏感性,并持续进行编程实践。
              66 1
              |
              5月前
              |
              编译器 C语言
              【C语言初阶】指针篇—下
              【C语言初阶】指针篇—下
              |
              5月前
              |
              存储 C语言
              【C语言初阶】指针篇—上
              【C语言初阶】指针篇—上