由浅入深 C语言

1,733 阅读14分钟

我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情


从基础开始入门C语言。


常量、变量

C语言中的数据类型包括

1.基本类型:

  • 整型
  • 字符型
  • 实型(浮点型)

2.构造类型:

  • 数组类型
  • 结构体类型
  • 共用体类型
  • 枚举类型

3.指针类型

4.空类型

💨常量

🎈常量分为:直接常量和符号常量


💨直接常量

🎈直接常量包括:整型常量,实型常量,字符型常量,字符串常量


整型常量

定义

就是整数,包括正整数,负整数,0

表示方法

十进制,八进制,十六进制

十进制:逢十进一,由0-9组成

八进制:逢八进一,以数字0为前缀,一般是无符号数,-011就不是合法的八进制常量。

十六进制:逢十六进一,以0x或0X为前缀,后由数字0-9和字母A-F组成,如0x12cd,0X6Fa。十六进制数一般是无符号数

注意

unsigned int无符号整型常量表示:在整型常量后加一个字母u或U,如233U

long int 长整型常量表示:在整型常量后加一个字母l或L,如11L


实型常量

定义

即实数,又称浮点数

表示方法

小数形式

由整数部分,小数部分,小数点组成,如果小数部分和整数部分为0时可忽略不写,但小数点必须存在!!

如:12.1,-.2(表示-0.2),3.(表示3.0)

指数形式

由尾数部分、字母E或e和指数部分组成,格式:+-尾数E指数

如:1.23E-2表示1.23*10的-2次方

注意:E的前后必须有数字,不可省略

✔注意

实型常量默认为double型,如果在数的后面加字母f或F,则认为是float型。


字符型常量

指单个字符用单引号所括起来的字符表示:如'a','B','='

必须满足两点:①只能用单引号括起来②只能是单个字符

✔注意

字符'4'和数字4是不一样的,字符'4'的值是52,对应ASCⅡ码值。

常见的ASCⅡ码值:'A' = 65 , 'a' = 97 , '0' = 48

✔常用的转义字符

\n 回车换行

\ddd 1-3为八进制所代表的的数

\xhh 1-2位十六进制所代表的的数


字符串常量

✔定义

由一对双引号括起来的零个或多个字符序列,如:"hello world"


💨符号常量

✔定义格式

#define 标识符 常量值

✔标识符

由数字,字母,下划线组成。首位必须是下划线或者字母

如:#define PI 233 ,定义一个常量PI,值为233,只能在此更改值!


💨变量

C语言中的变量必须先定义后使用

✔定义

类型说明符 变量名表;

类型说明符就是int double float char等;变量名表其实就是让你给变量取个名,别是中文的就好;别忘记定义好之后加个英文的分号。

✔初始化变量

其实就是给定义好的变量赋值,初始化有两种方式,看下面的代码

int a;
a=5;

运算符和表达式

赋值运算符和赋值表达式

简单赋值运算符

最简单的赋值运算符就是“=”,它的作用是将一个数值赋给一个变量。

例如:int a,b,c=1;意思是把1赋值给c。a,b不受影响只是定义一下。

复合赋值运算符

图片.png

%=是取余计算,比如5%4 = 1


赋值表达式

形式:   变量 = 表达式

注意:“=”左边必须是变量!  比如"3 = x"或者"a+b = 4"都是错的

执行过程:先计算表达式的值,再将结果赋值给变量


算术运算符和算术表达式

基本的算术运算符

图片.png

自增自减运算符

“++”和“--”,只针对于变量!

顺序问题:

int a = ++x; 先将x的值自己加1,然后赋值给a

int a = x++; 先把x的值赋值给a,x再自己加1

✔例题

#define d 2

int x = 5;

float y = 3.83;

char c = 'd';

A.(-x)++   B.y++  C.c++  D.d++

答案是BC,A是先运算()里面的-x,运算之后就是-5了,-5不再是变量。D中d是字符


算术表达式

和小学学的一样,只是把表达式在电脑上打出来,比如三分之一我们写成1/3


逗号运算符和逗号表达式

逗号","也是一种运算符,功能是吧多个表达式连接起来组成一个表达式,称为逗号表达式。

逗号表达式形式:

表达式1,表达式2,表达式3,...,表达式n;

从左到右一次计算每个表达式的值,并把最后一个表达式的值作为整个逗号表达式的值。

逗号运算符是双目运算符,其优先级最低,是左结合的


求字节运算符

格式:

①sizeof(表达式)或sizeof 表达式

②sizeof(数据类型名)

比如sizeof(int);如果打印出来就是4


语句和常用的基本函数

语句

C语言中,语句是一分号结尾的字符序列。是程序最基本的执行单位。

通俗点讲就是每条语句结尾要加上一个英文格式下的分号  ";"

复合语句除外,对于复合语句接下来会有介绍

语句归类

✔说明语句

用于定义程序所使用的变量与类型

如int a;   就是定义了一个整型变量

✔表达式语句

形式:

表达式;

如c=a+b;就是一个表达式语句,如果少了分号,只是一个赋值表达式

✔分支语句

C语言中有两种分支结构:①双分支if-else②多分支switch语句

这里只是提一嘴,后面会系统讲述。

✔循环语句

C语言中有三种循环结构:①for语句②while语句③do-while语句

✔转向语句

①break语句②goto语句③continue语句⑤return语句

✔复合语句

除了复合语句外的其他所有语句都以分号结束

复合语句是用一对大括号{}将若干语句顺序组合在一起形成的语句

例如:

{

int a = 1;

a = a+1;

}

复合语句中的单个语句必须加分号!

✔空语句

只由一个分号构成

✔函数的定义与调用

除了C语言内置的函数外,我们也可以自己定义函数和它内部的功能,后面也会系统讲述


常用的基本函数

输入输出函数

输入函数是scanf()

输出函数是printf()

格式:printf("格式控制字符串",输出项表列)

          scanf("格式控制字符串",输入项表列)


scanf()函数有一个很刁钻的问题,看下面代码

int a , b;
scanf("%d%d",&a,&b);
scanf("%d,%d",&a,&b);

有关逻辑的运算符和表达式

关系运算符和关系表达式

图片.png

注意:

  1. 关系运算符都是双目运算符,结合方向是左结合
  2. 关系运算符优先级等于算术运算符,但高于赋值运算符(=)
  3. <、>、>=、<=的优先级相同,优先级高于 ==、!= 。==、!=优先级相同

关系表达式

格式: 表达式1   关系运算符   表达式2

功能:比较两个表达式的大小,返回一个逻辑值(0或1)


逻辑运算符和逻辑表达式

逻辑运算符

逻辑非:!        右结合

逻辑与:&&    左结合

逻辑或:||       左结合

优先级:从上到下依次降低

逻辑表达式

格式:表达式1  逻辑运算符  表达式2

结果:0或1

C语言的逻辑值只有0和1,比如 !0=1  !1=0  !5=0  即C语言逻辑运算前只有0和非0,运算后的结果只有0和1,0为假,1为真。运算标准和数学相同

注意:

①若"&&"左边的表达式为,则可以得出整个表达式的值为假,那么 "&&"右边的表达式不再进行计算。

②若"||"左边的表达式为,则可以得出整个表达式的值为真,那么 "||"右边的表达式不再进行计算。


条件运算符和条件表达式

条件运算符

由"?"和":"两个符号组成,是一个三目运算符,需要三个操作数。是右结合的。

条件表达式

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

执行顺序:先计算表达式1的值,若值为1,表示条件为真,则只计算表达式2,并将结果作为整个条件表达式的值。否则只计算表达式3,并将结果作为整个条件表达式的值。

//举例
int a ,b;
a=5;
b=6;
a>b?a=7:b=5;

分支结构

C语言的分支结构有两种:①if-else语句②switch语句


if-else语句

一般形式如下:

if(表达式)

 语句1;

else

 语句2;


如果有多个语句,则写成

if(表达式)

{

 语句1;

 语句2;

}

else

{

 语句3;

 语句4;

}


if-else的意思是,如果if后面表达式的逻辑值为1,则执行if里的语句,如果不为1执行else里的语句。 看下面一段代码

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

🎈说明:

上面的程序我给a,b两个变量赋初始值,进入if里判断a是否大于b,很明显a小于b,表达式的逻辑值为0,所以去执行else里的语句。


if语句的嵌套

看下面一段代码

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

执行流程:

先判断a是否小于b(a<b),如果逻辑值为1则执行b=b+3;

如果()内逻辑值不为1则往下执行判断a是否大于b。如果逻辑值为1则执行b++;

如果都不满足就执行else里的a++;


switch语句

✔格式

switch(表达式)

{

 case 常量表达式1:语句1;break;

 case 常量表达式2:语句2;break;

 ......

 case 常量表达式n:语句n;break;

 default:语句n+1;break;

}

✔执行流程

表达式的值=常量表达式1的值,执行语句1,然后break跳出switch语句

表达式的值=常量表达式2的值,执行语句2,然后break跳出switch语句

表达式的值=常量表达式n的值,执行语句n,然后break跳出switch语句

其他情况,执行语句n+1,然后break跳出switch语句

Q:如果不写break会怎样?

A:比如你1里面没写break,那么如果执行了语句1之后他会继续执行语句2,直到见到break,如果一直没碰到break那么他会执行完下面的所有语句。

Q:不写default可以吗?

A:当然可以,不写的话,当程序执行完switch后面的表达式,找不到对应的case语句时,他自动退出switch,执行下面的程序


for循环

for基本语法

✔格式

   for(表达式1;表达式2;表达式3)

           循环体语句;

✔执行过程

  ①首先计算表达式1

   ②判断表达式2,若其值为真(非0),则执行循环体语句,然后执行第③步;若值为假(0),结束循环,转到第⑤步执行。

   ③计算表达式3。

   ④返回第②步继续执行。

   ⑤循环结束,继续执行for语句的下一条语句。

✔例子

   int sum = 0;

   int i;

   for(i=0;i<=n;i++)

    sum = sum+i;

   这样就可以实现从0-n的累加计算

其他格式

省略表达式1

   格式如下:

   for(;表达式2;表达式3)

           循环体语句;

省略表达式1时,可以将循环遍历赋初值放在for之前,注意此时不能省略第一个“;”

   比如上面的例子,等价于

   int sum = 0;

   int i=0;

   for(;i<=n;i++)

    sum = sum+i;


省略表达式2

   格式如下:

   for(表达式1;;表达式3)

           循环体语句;

省略表达式2时,表示不对循环进行控制,这时如果没有其他处理的话,会形成死循环。应避免这样使用for结构。


省略表达式3

   格式如下:

   for(表达式1;表达式2;)

           循环体语句;

省略表达式3时,可以在循环体语句中加入修改循环变量的值的语句。

其他注意事项

   for语句的一般形式中表达式1和表达式3也可以是逗号表达式

   for语句的一般形式中表达式2的值只要非0,就执行循环体

   for语句的一般形式中循环体语句可以省略

编程例题

  编写程序,输入10个数,输出其中的最大数

   思路:定义变量max存放最大数,将输入的第一个数赋给max作为最大数,在后续循环中,没输入一个数,都与max进行比较,若比max大,则将其赋给max,循环结束后,变量max中即为最大数。

#include<stdio.h>
int main()
{
  int i;
  folat x,max;
  printf("请输入第1个数:");
  scanf("%f",&x);
  max=x;
  for(i=1;i<=9;i++)
  {
    printf("请输入第%d个数:",i+1);
    scanf("%f",&x);
    if(x>max)
        max=x;
  }
  printf("10个数的最大数是:%.0f",max);
  return 0;
}

while和do-while循环

while循环

基本语法:

   while(表达式)

           循环体;

执行流程:

  第1步:计算表达式的值,若表达式的值为“真”,则执行第2步;若表达式为“假”,则转到第4步;

   第2步:执行循环体语句。

   第3步:返回第1步。

   第4步:结束循环,执行while语句的下一条语句。

注意:while语句的特点是先判断循环条件,后执行循环体语句。


使用示例:

//输入一个正整数n,计算n!
#include<stdio.h>
int main()
{   
    int i; long n, fact;
    i = 2; fact = 1;
    printf("请输入n的值:");
    scanf("%ld", &n);
    while (i <= n)
    {
        fact = fact * i;
        i += 1;
    }
    printf("%ld! = %ld\n", n, fact);
    return 0;
}

do-while循环

基本语法:

   do

           循环体

   while(表达式);

执行流程:

  第1步:执行循环体语句。

   第2步:计算表达式的值,若表达式的值为“真”,返回第1步;若表达式的值为“假”,则执行第3步。

   第3步:结束循环,执行do-while语句的下一条语句。

注意:do-while语句的特点是先执行循环体,后判断循环条件。因此,do-while循环至少要执行一次循环体。

改变循环结构的跳转语句

break

停止后期的所有的循环,直接终止循环。

continue

终止本循环,本次continue后的代码不会再执行,而是直接跳转到while语句的判断部分,进行下一次循环的入口判断。


一维数组

概念

   数组是相同数据类型的有序数据的集合。

   数据类型可以是基本数据类型们也可以是指针、结构体和共用体等类型。

   有序并不是按一定的顺序升序或降序,而是这些数据都有一个下标,带有一个下标的就称为一维数组,多个下标的就是多维数组。

定义和引用

定义

  一般形式为:

   类型名 数组名[常量表达式];

  表达式不能为变量,应为整型常量或符号常量

  如: int a[6];

   定义了一个整型的一维数组,数组名为a,有6个元素

说明:

   常量表达式用来表示数组元素的个数,即数组的长度。

   且C语言规定,数组元素的下标从0开始,不能为负数,下标的最大取值由“常量表达式”的值减1确定;例如上面的例子中a[6]有6个元素,分别是a[0]、a[1]、a[2]、a[3]、a[4]、a[5],没有a[6]。

引用

   形式:

   数组名[下标];

   下标必须是一个整型表达式。

   例如:

   a[3] = 5;

   a[2] = a[3] - a[a[3]-4];

   这两个语句的意思就是:先把5赋值给a[3]这个元素,然后下面就是先计算a[3]-4结果为1,那么a[a[3]-4] = a[1];下面语句就变成了a[2] = a[3] - a[1];意思就是把a[3]和a[1]的差值赋值给a[2]。


初始化

   形式:

   类型名 数组名[数组长度] = {初值表};

   初值表存放着数组元素的初值

   比如:int a[6] = {5,4,6,2,3,1};

   也可以省略数组长度,等价于int a[] = {5,4,6,2,3,1};

   但必须要注意:一旦[]里面有了数组长度,该数组的长度就固定了,如果你初值表少写了一个,会自动默认为0。

   下面省略数组长度的写法,比如你初值表只有5个数,那么他的数组长度就是5。


   静态存储:加了关键字static的话,没有初始化,只是定义了就会自动给所有数组元素赋0;

   比如:static int a[6];

  动态存储:只定义不初始化,数组元素值是不确定的。比如:int a[6];


如果一个数组中全部元素的值都为0,可以简写成:int a[6] = {0};

如果初值的个数大于数组长度,则会产生编译错误。