C语言快速入门

写在前面

本系列博客旨在记入博主学习C语言的的笔记和自己的一些理解。

希望通过博主的一些分享能够帮助学习c语言小白快速入门,和博主一起学习,快速进步,一起交流,互相督促,共同学习!(本系列持续更新)

本章目标

基本了解C语言的基础知识,对C语言有一个大概的认识。每个知识点就是简单认识,快速入门C语言,后期博主还会对每个知识点深入学习。

什么是C语言

C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

像英语,汉语一样,属于交流的语言,不过是人和计算机交流的语言。

C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。

语言的发展

036DF096-FC93-B65E-60D5-F73ADD18CF01.png

机器语言

第一代计算机语言称为机器语言。机器语言就是 0/1 代码。计算机只能识别 0 和 1。在计算机内部,无论是一部电影还是一首歌曲或是一张图片,最终保存的都是 0/1 代码,因为 CPU 只能执行 0/1 代码。

汇编语言

首先这么像机器语言编写肯定是可以的,但是这样太麻烦,而且很不好理解,所以后来就出现了汇编语言。

汇编语言就是将一串很枯燥无味的机器语言转化成一个英文单词。比如说:add 1, 2;

add 就是一个英文单词,这样看起来就稍微有一些含义了,即 1 和 2 相加。这个就是汇编语言。

C语言历史

C语言是由B语言发展而来,而后大多公司都使用C语言,不同的公司对C语言有自己的发展,和改进,而后出现不同的标准。

为了统一标准 美国国家标准协会(ANSI)先后C89 C99 C12等标准。目前比较权威的为c99。

而后在C语言的基础演变了C++,java 等面向对象的语言。

C语言的优势

广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言偏向于底层开发,如操作系统。

1、广泛用于底层开发

2,可移植性强,跨平台性

3,其编译器(将C语言转换成计算机语言)主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。

如VS(IDE集成开发环境)用的就是MSVC编译器。

第一个C语言程序

看了C语言的历史你肯定迫不及待想自己写一个C语言程序吧。

C语言环境的配置
APP推荐建议

VS2019下载地址

下载vs2013及以上版本环境

安装教程推荐

B站比特鹏哥教程如下

VS2019安装教程

88D9E949-80C3-18DD-2B8A-16463BD3FC04.png

第一个C程序

相信看了安装教程,你已经安装好了VS2019并且成功的创建第一个C语言项目吧。

那我们来写第一个C语言程序吧!

在屏幕中输出Hello world!

83CF5C46-8F4B-4AE6-C656-9979BF65AA6F.png是不是很神奇,短短6行代码便实现了我们想要实现的功能。

其实编程语言的出现,代码就是描述我们生活中的实际问题的!

注意事项

1, 一个项目中有且仅有一个主(main)函数

2,{ 是程序的入口 表示程序开始,} 便是程序的出口表示程序结束

3,因为printf是在stdio.h库中的,就好比生活中你使用别人的东西 ,使用了printf函数前需要向stdio.h打招呼所以 main 函数上面要包含库函数<stdio.h>

4 ,main前有一个int 说明该函数的返回值是整型(这些我们待会会学到,先记住)与最后一行代码return 0相呼应;

记住上面便能实现自己第一个C语言程序了快去试试吧!

数据类型
//整型
  //即数学中的整数   
    short 
    int
	long 
	long long 
//浮点型
 //数学中的小数(小数点可浮动)
   float  
   double

整型 可以表示生活中的 年龄 ,人数等整数数据

而浮点型 可以表示 生活中的体重,身高等带有小数的数据

想必你会疑问 :为什么会出现怎么多数据类型呢?

首先我们先来测试一下它们这些类型的内存大小

我们先来认识一个C语言运算符吧

sizeof()用来计算类型或者类型所创建变量所占内存空间大小(Byte)

计算机内存大小的单位

一个二进制位的0或1一位定义为1bit

单位 换算
bit (b/比特) 0/1(一个二进制位大小)
Byte (B/字节) 8bit
KB 2^10B
MB(兆字节) 2^20B
GB 2^30B

3826AA4C-3106-70D7-CC89-43BE336C952E.png注:C语言规定sizeof(long)>=sizeof(int) 即可

所以long类型在不同平台的大小不同,4/8

整型

根据生活中数据范围不同选择不一样的数据类型,合理的利用内存空间

比如 一个人的年龄 最多不超过500 所以用short短整型即可

浮点型

表示精度的不同,即小数点后面 位数长度不同

根据你的数据精度不同,合理选择浮点类型

常量和变量

顾名思义 常量就是不变的量,变量可以改变的量

常量

不可改变的量

如人的性别,身份证号码等等…

字面常量
66;
3.14
999
//*这些都是字面常量*
const修饰的常变量

const 修饰变量使改变量具有常属性(不可修改)

const int height=175;//创建了一个int类型的变量 const修饰后
                     // height不可改变
         height=200;  //err

但是该量还是变量只不过有了常量的不可修改属性

00A80E24-E08A-81BB-4202-C7969E08F04E.png代码中的两个错误

错误1,const 修饰的常量不可修改

错误2,const 本质还是变量不可定义数组长度

#define定义的常量

D1C268BA-26D5-5E05-6D26-E7B0A1908CB2.png

使用方法

#define MAX 100

#define +空格+常量名+空格+字面常量

注:常量名习惯大写

枚举常量

生活中有一些值可以一一列举

比如 :性别,三元色等等;

enum sexa  //枚举类型
{
   male,  //枚举常量
   female
};

enum sexa 就是枚举类型和int一样属于一种数据类型

1D4875E0-CABF-7AF9-59FD-8942C3F8D7A2.png该类型只有两种枚举常量可以选择 male和female

使用时赋值其他未定义的枚举常量会报错

81F05CC1-2A5C-F9DD-478D-7DD8313EF17B.png

每个枚举常量有自己的值 规定第一个值为0然后从上到下依次加一;

A974807E-93D6-2BCF-CDD1-FAC97876B844.png设置枚举常量可以赋初始值

变量

可以改变的量

定义变量的方法

类型 +变量名+常量;

int age=10;
    age=13;//可以修改
float pai=3.14;
char ch='w';
变量的分类

局部变量

定义在{}内的变量为局部变量

全局变量

定义在main函数外且不在{}内的变量

eg:

int glab=4;//全局变量
   int add(int x, int y)
   {
      int sum=0;
      // 局部变量
   }
   int main()
   {
      int a=6;
       // 局部变量
   }

是否想过当局部变量和全局变量同名时会怎样?

C278A64F-0587-3B78-402C-626CD63B23AE.png看到上面的结果想必你有了答案!

总结

上面的局部变量a变量的定义其实没有什么问题的!

当局部变量和全局变变量同时存在时采用局部优先原则

变量的作用域及生命周期

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

简单的说作用域就是该变量存在的范围 出了该范围该变量就失效

局部变量的作用域在它的局部范围即在{ }

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

int main()
  {
    int b=1;
    {
    int a=12;
    // a的作用域
    }  
   // b的作用域
  }

368C6C1D-74C3-47AD-317A-395F0C625FE1.png

可以看到全局变量的作用域是整个工程!

生命周期

变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段

  1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
  2. 全局变量的生命周期是:整个程序的生命周期。
字符串("\0")
" Hello world"

这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。

顾名思义字符串就是一串字符

C语言没有这种类型,所以通常存放在数组中

//字符
    char ch='w'; 
 //字符串
    char arr1[]={ 'H','e','l','l','o'};
    char arr2[]="hello";
字符串的结束标志’\0’;

注:字符串的结束标志是一个\0的转义字符。

在计算字符串长度的时候\0是结束标志,不算作字符串内容。

C840FAD5-DA31-164B-2122-C133337F22EA.png可以直观看到字符串arr2内有6个字符,而字符数组只有5个字符

B2855C48-1078-4BFE-ED20-377EA2E5D727.png打印arr1和arr2时因为打印函数遇到‘\0’才会停止打印

所以arr1在后面找了很久才遇到’\0’所以Hello后面都是随机值

那‘\0’算字符串长度吗?

ED112B70-469B-4823-0AF3-65D548C433C2.png

strlen计算字符串长度函数遇到’\0’计算结束

arr1找了31个字符才找到结束标志‘\0’

所以‘\0’并不算字符串长度

总结

字符串的结束标志是一个\0的转义字符。

在计算字符串长度的时候\0是结束标志,不算作字符串内容。

转义字符

当你要打印你的文件路径时

B3DF9634-2D79-BFB4-9FAA-69B160B9759F.pngA79320E9-24A0-C596-DCF2-0AAC10D52DE0.png就很迷,为什么这样呢?

这是就要提到转义字符这个概念了

难道转义字符是转变了该字符的本来意思?

下面看一些转义字符

140F17D3-B0A8-8F1A-64B0-DB0BD1DE10BE.png转义字符的使用

6B21328A-BCFF-83E6-A664-D7CD9A7C7C6D.png看了转义字符成功打印了正确的路径

自己可以去试试

C注释

1.代码中有不需要的代码可以直接删除,也可以注释掉

2. 代码中有些代码比较难懂,可以加一下注释文字

A65BBBEE-3BB5-EDB8-9D1F-CB6C7E8AD225.png

注释有两种风格:C语言风格的注释/xxxxxx/

缺陷:不能嵌套注释

C++风格的注释//xxxxxxxx可以注释一行也可以

VS默认c++风格

注释快捷键

27421587-4521-ECC9-22FC-6BE130892341.png9908389B-3CE2-B07E-3763-6247BD6020D1.png

选择(分支)语句

我们先来认识一下最简单的选择语句

eg:如果好好写博客,你就能获得粉丝,不写博客就没得粉丝!

if else 语句 如果 否者

253A6DA8-B455-80EC-5B8F-A29983AC59AB.png

怎么用带吗实现呢?

上代码

int main()
 {  
    int blog=0;
    scanf("你会好好写100篇博客>1\0");
    if(blog==100)
    {
    printf("收获粉丝\n");
    }
    else
    {
    printf("没有粉丝\n");
    }
    return 0;
 }
循环语句

有些事必须一直做,比如我要日复一日的写博客,比如大家,日复一日的学习。

for 循环

while循环

do while 循环

我们在拿上面的代码举例

用while循环实现

int main()
 {  
    int blog=0;
    printf("你会好好写100篇博客>1\0");
   while(blog<100)//当blog<100进入循环
    {
        blog++;   //blog数加一
      printf("再写一遍博客\n");
    }
      //循环结束来到这
      printf("很多粉丝\n");
     return 0;
 }
函数

函数是一个自我包含的完成一定相关功能的执行代码段。我们可以把函数看成一个“黑盒子”,你只要将数据送进去就能得到结果,而函数内部究竟是如何工作的,外部程序是不知道的。

函数了解

还记得我们一开始写的这个程序吗?

让我们先从main函数开始吧

int main()   
{
return 0;
}

函数名:main是函数名,函数名一般自己书写,就像创建变量一样

参数:()里面可以输入参数,参数由类型名和变量名组成, 因为main函数的参数为空(void)可以省略

返回值:返回值即是这个函数可以返回某些量 比如 int 说明这个函数最后会返回一个int的量,retun 0 说明该函数的返回值为0;某些函数不需要返回值 写成void

函数体:{ }里面的内容便是函数体,由很多语句构成

我们已经认识到了上面这个便是主函数,那我们自己尝试写一个函数

int Add(int x,int y)   //实现加法功能的函数  
   {   //函数体
      return x+y;//返回x+y的和
   }   
int main()
{
    int a=0,b=0,sum=0;
       sum=Add(a,b);  //调用该函数
}

学到这里,想必你已经对函数有了一定的了解

那就够了,哈哈哈其实博主现在也就只会这点点

数组

数组(Array)是有序的元素序列。 [1] 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。 [1] 这些有序排列的同类数据元素的集合称为数组。

数组是用于储存多个相同类型数据的集合。

int arr[5]={1,3,4,5};//int指数组类型是int
                      // arr是数组名
                      // [5]是数组长度
  char ch[]={'a','b','c'};//初始化时数组类型也可省略

F03059D8-DFC6-461B-8271-9B3104E5E2AE.png你是否注意点arr数组并不是从1开始而是从0开始

一开始初始化的arr[10]只是定义数组长度为10

而后面对数组的存放则是从0开始到9 ,10个数。

切记不可越界 对arr[ 10]进行操作是错误的。

操作符

指令系统的每一条指令都有一个操作符,它表示该指令应进行什么性质的操作。

可能你还是不太懂,没事看我介绍完,你就明白了。

比如数学中的加减乘除就是操作符!

算数操作符

简单地说,进行数学的算数运算就是算数运算符

符号 作用
+ 进行加法运算
- 进行减法运算
* 乘法运算
/ 除法运算
% 取余/取模运算

加减运算和我们传统数学运算一样。

注: / 当除不尽时,整形与整形相除会舍去余数得到整型商

若要得到正确商值,必须相除两数中有一浮点数,且要存放在浮点变量中;

int a=5,b=2;
//错误运算
   int sum1=a/b;          //2 两数都是整型 
   int sum2=a/(float)b;   //2 未存放在浮点型中
   float sum3=a/b;        //2  两数都是整型 
//正确运算
   float sum=a/(float)b;  // 2.5

37802AC7-E003-EB47-57A3-47A2B0BC5990.png

移位操作符

右移运算符 >>

左移运算符 <<

这里的位指的是2进制位

联系我们的十进制移位

小数点不动,数据移动

12.3 右移一位 >> 1.23 结果缩小10倍

12.3 左移一位 << 123. 结果扩大10倍

所以2进制的移位扩大2的倍数

因为计算机存储的位数是固定的,

数据是以补码的形式存储的。

我们来了解一下原码,反码,补码的概念。

符号位:正数的符号位用0表示 负数为1

原码:带有符号位的二进制位

反码:除符号位外原码的2进制位取反

补码:反码加1

为啥要引入补码这个概念呢?

因为计算机只能进行加法和移位操作

原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

12     二进制表示  1100
      储存在8位机器中 且有一位符号位
      符号位:正数的符号位用0表示  负数为1
        
              原码 反码,补码    0,0001100  
     -12  
     原码      1,0001100    
     反码      1,1110011   
     补码      1,1110100

所以移位移动的是补码的二进制位

因为机器字长的原因

移位后数据减少移位需要添加移位

正数

左移右边添0

右移左边添0

负数

左移右边添0

右移左边添1

CCD4F00D-5836-9357-4118-41D3EF345F83.png

移位可能会造成数据溢出,留着下次学习

位操作符

二进制位运算

运算符 作用
& 按位与 同真为真( 同1为1) eg:1&1=1;
按位或 一真则真 eg: 1按位或0=1
^ 按位异或 一真一假为真 eg:1^0=1;1 ^1=0

72A57D34-3C67-1B12-F662-4DD014937131.png

赋值操作符
=    +=    -=   *=   /=   %=   ......

赋值“=”可以和很多运算符组合,就不一一列举

1   a=a+3;   b=b*3;
  简化 2    a+=3;   b*=3;
            1和2等价

这就是赋值操作符的组合,C语言代码经常这样书写。

“=”在不同的位置含义不同,列如

int a=12;   //初始化非赋值
        a=10;   //赋值操作
单目操作符

单目就是只有一个操作数

操作符 作用
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
前置、后置–
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换

我们来介绍一些我们还没见过的操作符

!逻辑取反

DD29156E-2097-5C25-758A-BECC9915395C.png 计算机中以0为假,非0为真,所以非0取反后为0;0取反后为非0;

而vs下规定!0=1

! 通常用于判断语句,下次学习

&取地址操作符       * 解引用操作符

我们要先了解一下指针这个概念

指针就是地址,地址就是指针。

联系生活中的,图书馆借书,我们要找到我们要想要借书的位置,那个书架的位置就是它的书的地址,然后我们就可以根据这个地址找到这本书,就好比我们收快递的地址。

而计算机开辟空间存储数据,那块空间就是这个变量的的地址,通常用一串二进制代码表示。

int a=0;
  //&取地址操作
         int *pa=&a;//&取地址操作就是将a变量的地址赋给pa
               //pa变量就是a的地址码
  //*解引用操作
           
        *pa=12; 
       //*解引用操作符就是找到pa地址所指的那块空间存储的变量a赋值成12;

4C13AE10-C56F-FDA3-27B5-7A910903F807.png可能你还很懵,不要紧,后期还会学习

~按位取反操作符

同位操作符一样,将一个数的二进制位取反

++自加     -- 自减

我们通常写循环语句的时候要将 i 递增加减

i=i+1;     等价    i++;   ++i;

i=i-1;            i--;   --i;

是否发现上面 有前置加加和后置加加

++i 和 i++有什么区别吗?

5EB1F0AB-C70B-A64B-40A6-E62F0425925F.png

同样是自加,为啥前置和后置的计算结果不一样呢?

前置加加,先自加后使用

后置加加,先使用后加加

自减也是如此

所以++i 先计算i=i+1后再打印

而 j++ 先打印 j 再计算j=j+1;

(类型) 强制类型转换
int a=5,b=2;
     float sum=a/(float)b; //将int类型b强制转换成float类型
关系操作符
>
>=
<
<=
!=         用于测试“不相等”
==        用于测试“相等”

上面的操作符都用于判断俩数的大小关系 属于双目操作符

int a=10,b=12;
  if(a>b)
  {
  printf("a>b\n");
  }
  if(a==b)   //测试判断a与b是否等于
  {
   printf("a==b\n");
  }
  if(a!=b)   //测试“不相等”
  {
   printf("a!=b\n");
  }

注意:

测试等于关系操作符是“ ==” 而不是“=”

“=”是赋值操作符

逻辑操作符
&&     逻辑与   (数学中的并且)
||     逻辑或    (数学中的或者)

&&要左右两个表达时同为真,就是两个表达式结果都不为0

|| 一个表达式为真就为真 ,两个表达式结果有一个为非0就为真

逻辑运算符计算规则

||表达式依次计算,直到有一个表达式结果为非0就停止计算。

&&表达式依次计算,直到有一个表达式结果为0就停止计算

结果为真 整个逻辑表达式值为1;结果为假,整个逻辑表达式值为0

3AAA9BD4-AEFF-DA5C-F66C-B1B70A45B2F5.png

BF9F5FE9-4260-0FA1-FE80-5BB7AA7A32C5.png

你是否被这种题目给烦恼到,这么数和操作符;

为啥x=6 y=7 z=9呢?

逻辑运算值只有1和0,真就是1,假就是0,只要运算到有一个表达式的值非0就为真,就不会算下去了,&&一直算到0才不会进行计算了,++x前置加加先加加后使用,x++后置先使用后加加。

你试试看,是不是,就那样。

条件操作符

exp1 ? exp2 : exp3

// 求最大值
  int  max=0,a=3,b=5;
  if(a>b)
  {
   max=a;
  }
  else
  {
  max=b;
  }
 // 等价于
  max=(a>b)?a:b

是不是发现条件表达式超简洁!

exp1 ? exp2 : exp3

如果exp1为真,执行exp2,否者执行exp3;

逗号操作符

exp1, exp2, exp3, …expN

表达式从左到右依次计算,最后一个表达式即为运算结果。

7F6D060E-8B08-24F1-2167-990C5C4FECC3.png

关键字

auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while

一、C语言的关键字共有32个,根据关键字的作用,可分其为数据类型关键字、控制语句关键字、存储类型关键字和其它关键字四类。

1、数据类型关键字(12个):

char short int long float double signed unsigned struct union enum void

signed:声明有符号类型和和函数

unsigned:声明无符号类型和函数

通常和类型组合使用

unsigned char a=12;//无符号char使char 范围由 -128~127变成0~255

void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)

struct:结构体类型 union联合体类型

我们稍后学到

2、控制语句关键字(12个):

A.循环语句

for do while break continue

do:循环语句的循环体

与while一起使用

do{
   exp
  }while(exp1);

do while特点:先循环一次在判断循环条件,当exp1为真,再执行一遍exp语句

break:跳出当前循环,终止本层层循环

contiue:结束当前循环,开始下一轮循环

B.条件语句

if else goto

goto:无条件跳转语句

c.开关语句

switch case default

switch(input)  //一般input为输入的一个数
 {
   case 1:  exp1;    //input=1时执行exp1语句
   break;
   case 2: exp2;    //input=1时执行exp2语句
     break;
   case 3: exp3;
   .......
     break;  
     default: expN;    //当input的值为其他值时执行expN语句
     break;
 }

3 存储类型关键字(4个)

auto extern register static

register:声明积存器变量

extern:声明外部变量

static:声明静态变量

1.修饰局部变量

2.修饰全局变量

3.修饰函数

E8858659-4DE6-C3FC-F993-D493865ECB9E.png

const修饰局部变量,局部变量的生命周期改变,所以static int x在执行test2函数后,仍保留了x的值。

55FF2A76-E2D6-1E36-716F-4020A4E6FDDE.png

static修饰全局变量,全局变量失去了外部属性,static修饰的全局变量只能在当前源文件使用,不能在其他源文件使用

static修饰函数与修饰全局变量类似


指针

之前有了解过指针就是的地址,地址就是指针。

而计算机里面一个个划分的存储单元,就好比我们生活的房间。

而我们内存单元的编号就好比我们的地址,也就是指针。

内存

说到指针不得不提一下计算机里的内存

内存是电脑上特别重要的存储器,计算机中所有程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。

计算机里有32或64根地址线,32根地址线,一根地址线通电或者不通电,对应计算机的二级制语言1或0,而32根地址线的组合,就构成一串二级制代码,这串二进制数就是地址编号。

根据地址编号就可以找到计算机的那块空间

BDF48283-CA3D-FEF9-0A66-3E28AF37CF2F.png

int a创建了一个4字节的内存,而我们根据第一个字节的地址编号就可以找到a的4个字节。

所以a的地址就是第一个字节的地址编号。

057DCB69-28DF-880F-5219-B09589F90601.png

&取地址操作符,int*pa=&a就是将a地址存到int*类型变量pa中,*pa就能将a这块空间重新分配。

指针的应用远远不止这些,我门后期还会深入学习!

结构体

回到一开始我们所介绍的编程语言,代码的出现就是为了解决生活中的问题!

如果我们想要表示一个人的属性,一本书的属性,好像我们并没有类型用于表示,所以出现了结构体类型!

struct peo  //自定义一个结构体类型 struct peo
{
  char name[10];//定义一个char数组存储名字
  int tele[11];  //存储号码
  char sex;     //存储性别信息
}

B47FCCE7-EB2C-28A5-974B-C2989649558A.png

这就是结构体的使用方法!

收藏 (0)
评论列表
正在载入评论列表...
我是有底线的
为您推荐
    暂时没有数据