C语言基础

简介:

c语言在编程语言中是偏底层的语言,像JavaScript,以及java。都是在c语言的基础上编译出来的。像操做系统:unix ,linux ,windows都是依靠c语言开发出来的,使用c语言能够开发windows应用程序。在c语言中不像在javascript中那么随意,在c中每写一条语句都必需要以 ; 进行结尾。javascript

c语言的编码方式:

c语言的编码方式,在用char类型声明的窄字符会使用到Ascll码,用char类型声明的窄字符串和在Wchar_t声明的宽字符和宽字符串都不使用Ascll码,对于wchar_t声明的宽字符和宽字符串通常使用UTF-16和UTF-32进行编码的,对于char类型声明的字符串是根据编译器或者源文件的编码方式去编码的因为编译器的不一样使用的编码也不一样 。html

数据类型:

c语言的数据类型大致分为如下四种:java

  • 基本类型linux

    基本类型又分为下边这几种:编程

    • 整型windows

      整型用: int 进行表示在内存中占4字节 数组

      整型又分为下这两种:缓存

      • 长整型编程语言

        长整型用: long 进行表示在内存中占8字节 编辑器

      • 短整型

        短整型用: short 进行表示在内存中占2字节

    • 浮点型

      浮点型又分下边这两种:

      • 单精度浮点型

        单精度浮点型用: long 进行表示在内存中占4字节

      • 双精度浮点型

        双精度浮点型用: short 进行表示在内存中占2字节

    • 字符型

      字符类型使用 : char 进行表示在内存中占1字节

      这种用char代表的字符类型还有一种名称叫窄字符。

      像这个char只能处理ASCLL码有的在字符处理不了中文以及其余语言的字符


      对于像除了Ascll码值之外的字符咱们用 : wchar_t 表示它在内存中占的位置由编译器决定。因为这种类型在的头文件中因此咱们要引入这个头文件,另外若是咱们在单个字符前面加上大写字母L 例: char str = L'A';那么这个字符就会变为宽字符。还有宽字符的输出用不到下面那个通用的输出方法,咱们要用到wchar.h头文件中的putwchar()或者wprintf()函数。
  • 枚举类型

  • void类型:

    在javascript中void是一个运算符 它用于计算它旁白的表达式,不管表达式是什么它老是返回的是undefined

    void在C语言中它是无类型的也就是没有类型的。

  • 复合类型

数据类型转化:

对于数据类型转换又分为如下两种:

  • 自动类型转换:

    自动类型的转换是不须要咱们去干预的,好比在赋值运算中,右边表达式的值与左边的数据类型不一样会自动将右边表达式转换为跟左边同样的类型。

  • 强制类型转换:

    强制类型转换是咱们本身去进行的转换转换方式式这样的:(新类型) 表达式

对于自动和强制类型转换都只是根据需求时去进行的临时转换,它们不会实际的改变数据的类型。

声明变量:

c语言中声明变量是这样的 : 数据类型 变量名=值

还能够 数据类型 变量名; 变量名=值

在c语言中声明变量时的变量名不只仅表示它后边的值它还表示它的值在内存中的地址,      &变量名       这个&变量就是这个变量的值在内存中的地址。*变量名表示一个存储单元里的数据。

注:字符类型的变量的值要用 '' 包裹而且只能一个字符。c语言中变量能够从新赋值可是不能一个变量声明两次。(在js中的ES5的语法中用var声明的变量能够声明两次且不会报错,在ES6语法中变量不能声明两次不然会报错

运算符:

运算符基本上和js中的差很少。

  • 基本运算符:

    加法,减法,除法,乘法,取模运算,自增,自减

  • 关系运算符:

    大于,等于,全等,大于等于,非等于

  • 逻辑运算符:

    且,或,非

以上这些运算符和js中的同样进一步了解可参考:juejin.im/post/5ce109…

输入和输出:

输入和输出分别使用如下这几个函数

  • 输入: scanf()

    这个scanf输入函数基本上跟printf差很少只不过一个是输入一个是输出,它里边也有格式控制符 。 例:scanf("%d\n" , &a) 这个就是输入前边用""包裹是格式控制符,后边的是a是变量 & 是符号,意思是将输入的值赋值给变量a,这个函数是当用户输入完成时会将用户输入的值存进缓存区,当用户按下回车时才会读取


  • 字符以及字符串的输入使用如下这几个函数

    • 单个字符的输入使用:getchar()函数它用于输入单个字符,例:char isd=getchar(),这个函数也是当用户输入完成时会将用户输入的值存进缓存区当用户按下回车时才会读取。

    • 输入字符串用这个函数 : gets() 括号里写你须要将用户输入的值赋值给哪一个变量。例: gets(asd) 这个表示将用户输入的值赋值给asd这个变量。虽然scanf()也能用于输入字符串只需写上格式控制符%S便可,但scanf遇到空格时会认为输入结束了,gets会将空格认为字符串的一部分。


  • 输出: printf()

    这个是格式化输出函数,在输出的函数中这个是最经常使用的,这个printf中格式控制符具体能够查看printf输出函数格式化控制符详解,例: print("%d\n",a) 这个括号里前边用""包裹的就是格式控制符,后边的是变量

判断语句:

c语言中的判断语句基本上和js中的差很少,

c语言中的判断语句大体有如下几种:

当设置判断的条件时就要用到上边的关系运算符注意:在js中有boolean值ture和false在c语言中没有这个概念在c语言中0为false,非0为true。

  • if else

    例:

    if(条件){

    条件为真时执行这里的代码;
    复制代码

    }else{

    条件为假时执行这里的代码;
    复制代码

    }

  • if else if

    例:if(条件1){
    条件为真时执行这里的代码;
    复制代码

    }else if(条件2){

    当条件1为假时进行下一步判断条件2条件2为真时执行这里的代码;
    复制代码

    }

  • switch

    switch大多用于在多条件判断时

    例: switch(变量){
    case 1 :当变量等于1时执行这里的代码;break;
    case 2 :当变量等于2时执行这里的代码;break;
    case 3 :当变量等于3时执行这里的代码;break;
    case 4 :当变量等于4时执行这里的代码;break;
    case 5 :当变量等于5时执行这里的代码;break; 
    case 6 :当变量等于6时执行这里的代码;break;
    default:当变量不知足以上条件时执行这里的代码;break;
    复制代码

    }

    注:例子里边的变量能够是用户输入的变量 而后case是固定格式 case后边必须是整数或者整数的表达式,break必须写,break的意思是当变量知足某个时执行完代码后讲跳出判断再也不继续向下判断,最后的default是可写可不写的default的意思是当变量不知足以上全部条件时将执行default那的代码。

  • 三元运算符,这个也是一种判断语句,主要用于一个条件的判断

    例: 条件?当条件知足时执行这里的代码 : 当条件不知足时执行这里的代码;

循环语句:

c语言中的循环跟js中的循环也几乎都同样。

  • while循环

    例: while(条件){
    当知足条件时执行这里的代码,
      若是条件一直知足会一直执行这里边的代码直至不知足条件将跳出循环
    复制代码

    }

    当条件一直知足时会一直执行代码成为死循环。

  • do{}while()

    例: do{
    要循环执行的代码
    复制代码

    }while(条件)

    do while循环实际与while差很少只有一点不同,while循环会先判断条件再去执行代码若是条件不知足则不会执行代码,do while循环会先执行一遍代码而后再区进行条件的判断,条件为真则继续执行代码条件为假则再也不继续执行代码。

  • for循环

    例:for(语句1;语句2;语句3){要循环的代码;}
    例子中语句1=初始值,语句2=结束条件,语句3=对值的操做 注意:语句之间要用分号分割,最后一个语句3不用分号,语句1只用1次 执行顺序:先执行语句1和语句2判断语句1是否知足结束条件若是知足进入循环体(要循环的代码就是循环体),不知足跳出循环,第一遍执行完以后执行语句3,而后再去执行语句2,判断是否知足条件若是知足进入循环体不知足跳出循环体。循环执行步骤2直至不知足条件退出循环。

    注意:在for循环中若是不带{},好比:for(语句1;语句2;语句3)那么它会将下一条带分号的语句座位循环体。

注:在循环中有一个break关键字用来跳出循环一般跟判断语句结合使用。还有continue关键字是跟if esle 结合使用当continue会跳出当前循环强制进入下一次循环。

数组:

注:在c语言中的数组是静态的也就是说数组不能向数组内部进行增长和删除功能,而在js中数组向数组内部进行增长和删除功能的这种数组叫作动态数组。

咱们把一组数据的集合叫作数组,c语言中的数组跟js中的数组略有不一样。

数组有如下几种类型:

  • 一维数组

    例 : int a[4];这样就声明了一个整型数组它的长度为4,它的每个元素都为一个整型。

    数组的赋值方法有如下几种:

    1. 数组类型 数组名 [自定义数组的长度] 数组名[下标]=值
    2. int 数组名[数组的长度]={数组的第一个元素,数组的第二个元素,... ,数组的第N个元素}

    咱们一般还经过for循环来为数组赋值。

    注意:声明数组时数组名前面的类型时什么类型那么数组里的每一个元素就为何类型。若是数组中的某个元素未赋值那么他的值默认为0。/p>

  • 二维数组

    能够把二维数组当成一个表格,它有行有列,

    例: 数组类型 数组名[数组中一维数组的长度][数组中二维数组的长度]

    二维数组的赋值:

    数组类型 数组名[一维数组的长度][二维数组的长度]; 数组名[一维数组某个元素的下标][二维数组某个元素的下标]=值;

    也能够经过for循环来为二维数组赋值。

  • 字符数组

    js中有string类型的被称为字符串,而c语言中没有字符串的概念只有单个字符因此在c语言中咱们把一串字符串称为字符数组。

    字符数组的定义是这样的:

    char 字符串名 [字符串长度]="这里是你的字符串"

    另外在c语言的字符串中要以\0去进行结尾不然这个字符数组是没有结尾的。

    咱们能够引入< string.h >头文件而后利用strlen(字符串名)来求出字符串的长度,另外字符串的长度不包括最后结尾的\0。

    另外输出字符串有两种方式:printf("%s\n",字符串名)和puts(字符串名)

    输入字符串也有两种方式scanf("%s",字符串名)和gets(字符串名)

    输入字符串的这两种方式有必定的区别,经过scanf()输入的字符串遇到空格就会认为字符串结束了而gets()不会。可是scanf()能够指定字符串输入的类型,

    c语言向咱们提供了对于字符串的处理函数不过这些函数是包含在string.h的头文件中的咱们必需要先引入< string.h >头文件才能使用这几个函数这几个函数分别是如下几个:

    • strcat(x,y)

      strcat(x,y)函数是用来进行字符串拼接的只要咱们在strcat的函数里写上两个参数x和y那么y的字符串就会拼接到x字符串的后边,不过前提是x字符串在内存中所占用的空间可以同时存放下x和y两个字符串的空间不然会出现数组越界的问题。

    • strcpy(x,y)

      strcpy(x,y)函数是用来拷贝字符串的只要咱们在strcpy(x,y)函数中写上两个参数x和y那么x字符串的内容就会被y字符串的内容覆盖掉。可是前提是x字符串在内存中占用的空间可以存放下y字符串的内容不然就会拷贝的不全面。

    • strcmp(x,y)

      strcpy(x,y)是字符串的比较函数,字符串自己是没有大小的咱们对字符串进行比较是比较ascll值从两个字符串的第一个字符开始一一比较若是x字符串跟y字符串相同那么返回0若是x字符串大于y字符串那么返回大于0的值若是x字符串小于y字符串那么返回小于0的值。

数组的越界和溢出:

  • 数组的越界:

    数组中的一项元素都是有它的下标的当咱们去访问数组中没有该下标的内容时会发生数组越界的问题,一旦数组越界编译器在编译时就不能进行正常编译还会报给咱们一些彻底看不懂的报错。

  • 数组的溢出:

    当数组的长度大于咱们定义数组时数组的长度时就会产生数组溢出的问题,当咱们的数组溢出时编译器在编译时会给咱们报错,正常的数组溢出就是在输出数组时多出去的部分会被丢弃可是若是是字符串形式的数组溢出时咱们还输出数组时编译器可能会正常经过可是输出的就不是正常的了,因此咱们在定义数组和给数组赋值时要细心避免数组溢出的翁提发生。

函数:

其实c语言中的函数也基本上都跟js中的同样可是在c语言中只有一个主函数且只会执行这一个主函数。

在c语言中函数有如下两种:

  1. 第一种是c语言提供给咱们的函数,c语言有15个头文件被称为标准库,这些库里边给咱们提供了丰富的函数供咱们能够去直接去调用。

  2. 第二种是咱们本身去定义的一个函数咱们在.c文件中能够本身去定义一个函数而后去进行调用。

在c语言中咱们都会见到这样的结构

例: int main(){
函数体;
return 0;
复制代码

}

这个main函数就是c语言的主函数且c语言只会执行这一个主函数,main函数能够去调用其余函数可是却不能它自身却不能被任何函数去调用。咱们能够在主函数上方或者主函数内部去自定义函数而后再主函数主区调用自定义函数。

c语言去定义一个函数是这样的,函数类型 函数名(参数){

函数体
return 变量;//这个return时函数在去调用时函数的返回值,在咱们去定义函数时函数时什么类型的那么函数的返回值就是什么类型的
复制代码

}

c语言中函数去调用时这样调用的:

函数名(参数)

另外在c语言中函数也是有做用域的全部在函数内部包括主函数声明的变量都是局部变量,在函数函数外边声明的变量被称为全局变量。

在c语言中函数也有递归递归函数,关=关于递归函数通俗的解释就是在函数内部去调用函数自己。

c语言的预处理命令:

什么是c语言的预处理命令?

在咱们去编写.c文件时都会在代码的第一行去写 #include <头文件>。像这种以#开头的命令就叫作预处理命令。咱们写的每一个.c的文件都是一个可执行程序的源文件,只有咱们经过编译器去将咱们的.c文件去进行编译的时候才会生成一个可的执行程序。#include是引入头文件的命令一个#include只能引入一个头文件,要引入多个头文件就须要多个#include

宏?

在c语言的预处理命令中有宏的定义,咱们能够把宏看成一个定义常量的用法由于咱们一旦使用了预处理指令去定义了一个值或者表达式那么咱们在下边是没法改变的。宏是经过预处理指令来进行的关于预处理指令指令大体介绍如下几种:

  • #include <头文件>

    这个指令是用来引入头文件的

  • #define 自定义宏名字 字符串或者表达式

    当咱们在代码中用到这个自定义宏名时那么这个自定义宏名会被替换成它后边的字符串或者表达式。

    用法:

    #define 宏名(参数) 表达式或值

    调用宏: 宏名(参数)

c语言指针:

在c语言中指针是一个很重要的概念它表明了数据在内存中存储的位置,在js中咱们的指针是this。

当咱们去声明一个变量名为a的变量时,int a=1; 它的值是存储在内存中的它的变量名a就表明的是这个数据在内存中存储的地址。而且这个变量名并非真正的地址它只是该数据在内存中存储的地址的一种代称罢了在咱们的编译器去编译的时候这些变量名都会被转换成地址而后当咱们的编译器去编译时会找到这些变量名表明的地址从而去获取数据。

有了指针咱们能够经过 *来定义指针变量不过*号的用法有如下几种:

  • 在运算符中在

    在运算符中*号表示的是乘法

  • 定义指针变量

    当咱们去定义指针变量时咱们须要在变量名前加上*以表示它是一个指针变量

    例:int *变量名;

  • 给指针变量赋值:

    例: int a=1; int *b=&a;

    &a表示的是变量a在内存中存储的地址。这时咱们去输出*b那么它的值就是变量a的数据在内存中所存储的地址。咱们也称为b指向了a。

  • 经过指针变量去修改内存中的数据

    例: int a=1; int *b=&a; *b=12;

    咱们知道这时候的b指向a,也就是*b表明了a的数据在内存中存储的位置,可是当咱们去给*b从新赋值的时候咱们是给*b所表明的内存中的地址里的数据修改了修改为为了给*b从新赋值的值。

  • 数组指针:

    咱们在定义数组要给出数组名和数组的长度,数组中的每一个元素在内存中的地址都是紧挨这个,一整个数组占用的是一整快内存,这时咱们的数组名也表明的是一个地址不过它默认的是只表明数组中下标为0的元素所在内存中的地址。

    若是一个指针指向了数据那么咱们就称它为数组指针

    例: int arr[10]=[1,2,3,4,5,6,7,8,9]; int *q=arr;

    这时*p表明的是数组arr中的下标为0的元素的地址咱们若是想访问下一个元素可使*p++.在这可能会有疑问为何在这不适用&arr,由于arr自己表明的就是一个地址了就不须要再去使用&去获取它的地址了。

  • 字符串数组指针:

    上边写了字符串自己就是一种字符数组,只有用定义数组的方式能定义一个数组,可是经过指针咱们又引出了一种新的字符串的定义方式。

    例:char zi="yuzhong"; printf("%s",zi);

    咱们能够经过指针的方式去定义一个字符串不过这种,这种指针叫作字符串指针,还有就是这种方式声明的字符串称为字符串常量。虽然使用这种定义字符串可是它跟字符串数组上有着本质上的不一样:1.这种方式定义的字符串叫作字符串常量它只能去读写但式不能去改变。2。存储方式的不一样使用字符串数组存储再全局数据区或者栈区,字符串常量存储再常量区不能进行更改。

何时能用到指针变量:(如下只是简单的举了两个例子)

  1. 当作函数参数传递进去,咱们我已在在函数将经过指针将咱们须要的参数的地址传递进去,如下是一个最简单的例子

    例:int a=1,b=2; int one(int *a,int *b){

    函数体
    复制代码

    } one(&a,&b);

  2. 把数组传递给函数

    咱们知道数组是一组数据的集合,它不能一次性的所有传递函数咱们能够经过指针将数组传递进去而后对数组进行操做。

使用指针做为函数返回值:

c语言容许函数的返回值是指针咱们将这种返回值为指针的函数称为指针函数

二级指针:

在c语言中还有二级指针的定义,什么是二级指针?

咱们上边写的那种是叫作一级指针它直接指向某个变量的地址里边的内容。在c语言中咱们把*变量名叫作一级指针,**变量名叫作二级指针,***变量名叫作三级指针前边有几个星号就是几级指针

例:
#include <stdio.h>
   int main(){
       int one =10;//这是一个变量one
       int *two=&one;//变量two前边有星号且它的值为&one,&one表示的是变量one的值在内存中的地址而后*two指向这个变量one的地址也就至关于变量two就是one的值
       int **three=&two;//变量three前边有有两个星号且它的值为&two,&two表示的是变量two的值在内存中的地址而后**three指向这个变量two的地址也就至关于变量three就是two的值
       int ***four=&three;//变量four前边有有三个星号且它的值为&three,&three表示的是变量three的值在内存中的地址而后***four指向这个变量three的地址也就至关于变量four就是three的值
       printf("%d",***four); //这里最后输出的是变量one的值。
       return 0; 
   }
复制代码

空指针:

在js中咱们的数据类型中有一种类型叫作null,就是表示为空。注意在js中不要把null和undefinde搞混由于undefinde表示未定义而null表示为空。在c语言中null也表示为空只不过它不是数据类型而是指针,null就是表示空指针。像下面这段代码:

错误的代码:
#include <stdio.h>
   int main(){
       int *one;
       gets(one)
       printf("%d",one);
       return 0;
   }
复制代码

像这段代码咱们就是声明了一个指针变量可是却没有给他赋值,这段代码是错误的可是能编译成功,若是咱们使用的是文本编辑器进行编辑的这段代码而且使用了gcc进行编译能编译成功可是输出出的东西确实未知的。若是使用VS进行编译调试那么会给咱们报错。

还有就是当咱们去声明一个变量时可是未对变量就行赋值却选择输出了这个变量会给咱们报错。咱们能够在声明变量时给变量赋值为NULL,注意在js中给变量赋值为NULL不区分大小写可是在c语言中NULL必定要是大写。当咱们把变量赋值为NULL再进行输出就会输出(null)

void*指针

void* 上边提过void是一个没有类型的也就是类型是不肯定的可是void*指针是一个指针它也指向了内存里的某个地址的数据可是内存里的数据类型是不肯定的因此咱们在使用void*指针时要进行类型转换。

相关文章
相关标签/搜索