当前位置 : 主页 > 编程语言 > c语言 >

C语言初阶

来源:互联网 收集:自由互联 发布时间:2023-09-07
前言: 认识C语言: 什么是 C语言 ,C语言是一门 高级编程语言 ,是从最开始的机器语言(二进制指令)、汇编语言、B语言一路演变改进而来,在计算机历史上有举足轻重的地位,直到

前言:

认识C语言:

  什么是C语言,C语言是一门高级编程语言,是从最开始的机器语言(二进制指令)、汇编语言、B语言一路演变改进而来,在计算机历史上有举足轻重的地位,直到现在仍在发挥它的作用。

  C语言是有遵循标准的,常见的有C89,C90,C99标准,最初由美国国家标准局制定了一个ANSIC的C语言标准

  C语言初阶知识:第一个程序

  初来乍到,当我们来到这世上,一切都是很简洁的,C也是一样,请看第一个程序:

C语言初阶_C语言

  认识新事物先分解来看,这个代码是由主函数main函数printf()打印函数return返回值#include预处理指令组成的一个整体。

 如果我们在自己的编译器上按ctrl+f5(编译、链接、运行代码),你会看到这样的一个界面:

C语言初阶_C语言_02

  它在你屏幕上将hello world输出出来,是不是很帅或觉得神奇?

第一个程序的解析

  认识使用main函数。main函数是程序的唯一入口,一个工程只能有一个main函数,使用函数需要小括号()贴在函数名后面,意思是调用该函数,可以认为main函数的接口是操作系统。(绿色部分可以暂时不用理解,不理解问题也不大的,慢慢学就懂啦)

  int是一个数据类型,int是整型的英文缩写,int main前面的int的意思是,当main函数调用完(代码都被计算机编译完)后会返回一个整数给到调用main函数的一方(操作系统那一方叫主调函数,主调函数是调用函数的一方,main函数是被调函数)。return是返回的意思,返回一个0(整数),恰好对应int main要求返回一个整型,前后呼应。

  printf()函数是C语言提供的一个打印函数,用双引号括起来的部分是要输出的到屏幕上的内容,printf()是C提供给我们的,我们都知道用别人的东西要跟人家打声招呼,经过别人同意你才会去用,这里我们使用#include <stdio.h>来和人家(C标准函数库)打招呼。

  print()、return都被包含在代码块{}里,里面可以写代码。ok,解析到这里,你已经懂了一点了,但你肯定还有疑惑的地方,就是写代码的格式问题,究竟什么时候有空格呀?为什么print()、return 0后面都有个分号;,而#include没有,main没有。

  这些你先不用担心,看完下面的小小解释,以及本博客后面的代码你就慢慢会这样写格式啦。

  先说空格的问题吧,int后面需要空开,不能写成intmain,main与()不能空 开,不能写成main ()。接下来说分号;的使用,C语言中,其实一条语句,完结后都需要加上;来结尾,就像是一句话,有了句号才是完整的,return 0;就是一条完整的语句。

  总的来说就是,一个独立的“单词”,你就得与其它”单词”用空格分开,不能混在一起,另外就是为了代码容易看,赏心悦目,有必要空开。

  好的说完这些,开始我们的编程之旅吧,启程前,需要你带上你空杯的心态(好好学,戒骄戒躁)。

第一章

1.1变量和常量

  变量:顾名思义,会变的量。C语言中变量的创建是由数据类型来创建的。

  常量:不会发生改变的量。

1.1.1数据类型

  C语言的数据类型有int呀,char(字符类型)、short (int)短整型、long (int)长整型、float(单精度浮点型)、double(双精度浮点型),它们都是C语言的内置类型,但仅靠内置类型是不够的,后面我们还会讲到需要自己定义的自定义类型,比如指针,数组,结构体,字符串这四种,都是非常重要的。

  char类型:是用来创建字符变量的,比如‘b’、‘i’、‘t’等用单引号括起来的字母是字母字符,‘5’、'2’、'0'是数字字符,凡是你在键盘上能键入(输入)的键都可以是字符。(char字符类型是属于整型家族的,因为有一个ASCII码表,给每个字符都编了个ASCII码值,这个值是整型,所以char本质上也是整型)

  float:是用来表示带小数的,比如3.14、123.4都是浮点数,float和double的区别是在精度和空间大小上的区别,double的精度更高,一般可以表示小数点后十五位。

  short、int、long:这三个都是整型,但我们听名字细节就可以知道一些东西,它们虽然都是整型,但用它们来创建整型变量,变量的内存空间大小有差异。

  数据类型为什么需要这么多,其实数据类型规定了开辟内存空间的大小以及以何种视角看待内存中值。简单来讲short (int)类型创建的变量内存空间大小小于int类型为变量开辟的内存空间大小,内存中存的都是二进制,是以整型的视角看待内存中的二进制的。

1.1.2创建变量

  了解完数据类型,就可以来创建属于我们自己的变量了,请看代码:

C语言初阶_C语言_03

  变量的创建是: ”数据类型 变量名 = 值;”,变量名按你需要取名,取名规则是,不要重复,不要和C语言的关键字冲突,像int就是C语言的一个关键字,C语言总共有32个关键字,但一般起名都是正常的,不会冲突。

  补充:VS底下写出一个小数如5.5,编译器默认是double类型,写成5.5f就是表示单精度啦。

  如果有比较细的细节,我尽量在代码注释里讲出来,因为写在里面会使文章显的冗长,请读者理解理解^.^

  注释:双斜杠//后面的就是注释内容。注释掉的内容编译器不会编译,所以不需要的代码可以注销掉,注释还有的作用就是它的本意,在写代码的时候,要养成注释的习惯,让别人好懂,让自己更容易快速理解以前编写时的思路。

  双斜杆是C++的注释风格,也是最常用的,C的注释风格是/*.....*/,注释内容可以是连续多行,不过缺点是C的注释风格不支持嵌套,很容易使需要注释掉的代码漏掉。比如: 

/*int main()
{
  int a = 0;
  scanf("%d", &a);*/
  return 0;
}*/  //这里就没能把return 给注释掉 我们本意是想头尾匹配的

1.1.3常量分类  

  常量也有分为字面常量#define定义的标识符常量const修饰的常变量enum枚举常量

  字面常量:字面上的不变的量,比如3.14就是字面上的浮点型常量,当你写出一个常量后,它会自带某个数据类型的属性,再比如3是整型常量。

  #define定义的标识符常量:标识符是一个标签的存在,看到雾山五行,你第一反应就是,这是国漫山水画的代表,#define也一样,比如你使用#define Max 100定义Max这个标签,编译器就知道它是100,是一个常量,不要因为是字母Max就以为它是变量。

  const修饰的常变量:“常”变量,本质上它还是个变量,前面的常是一个修饰,意味着这个变量有常量的属性,我们知道变量是可变的,而当变量被const修饰后,就不再可变了,请看代码:

C语言初阶_C语言_04

  enum枚举常量:enum是枚举关键字,枚举是一一列举的意思,这里我们直接看代码容易理解。

C语言初阶_C语言_05

  这里面的Red、Yellow、Blue都是枚举常量,它们是有值的,依次是0、1、2这样的常量值,这就是枚举常量。这里说到Red不能在main里面被修改,那是不是有其它修改的方法在呢?请看:

C语言初阶_C语言_06

  get到我的意思了吧 \^.^/,Red在定义的时候被我们赋成100开始,按顺序往下加1,Yellow是101。

  讲到这里,还有一点补充的是,区分变量是初始化还是赋值在时间上的不同,请看代码:

C语言初阶_C语言_07

  那么,创建b没有进行初始化,b里面有没有值,程序员需要掌握的一个重要技巧来了,调试!,按住fn+f10进入调试状态->菜单栏上调试->窗口->监视里任何一个都ok->输入监视对象(变量名),可以看到b的值很奇怪,是个不可猜测的值,我们称之为垃圾值或随机值,这样我们就知道了没初始化的变量会自动放一个随机值在里面,所以变量尽量初始化,不知道就初始化0。

  局部变量和全局变量,什么是局部变量,什么是全局变量。请看代码:

C语言初阶_C语言_08

 “%d”以整型打印a,可以这样理解,把a的值替换到%d的位置。

  作用域和生命周期的概念:就局部变量a的作用域来讲,在进入main()函数的代码块时,a变量创建,出代码块时a变量自动销毁,这个代码块就是a变量的作用域,它的生命周期是,在创建是生命周期开始,销毁时生命周期结束。

  全局变量b的作用域是整个文件,生命周期是整个工程,因为b在哪都可以用,在一开始就被创建了,只有main()函数调用完才销毁,而main()又是整个工程的代名词,固如上所述。接下来我们来看一个特例:

C语言初阶_C语言_09

  当局部变量名和全局变量名冲突时,在代码块内的printf("%d", a)是局部变量优先,打印的10,这里还涉及一个问题是,编译器跑不跑得过去的问题,因为有变量名冲突了,是可以跑的,但如果是同时定义在局部或全局的变量名相同,会报警告且跑不过,而这是一个在全局,一个在局部,虽然能跑,但还是不要让变量名冲突,冲突了局部优先

1.2转义字符和操作符

  \n前面有提到是换行的意思,它是一个转义字符,在打印的时候不是打印出\和n而是换行,转义字符有挺多我们慢慢积累,需要注意的是转义字符是算作一个字符不是两个,不要看有两个字符就是两个。

1.2.1认识操作符

  算术操作符:+-*/%,加减乘除和取模,前面四个大家耳熟能详,但C语言中我们要讲一些/和%,因为与数学有点不同。

C语言初阶_C语言_10

  除法求商,取模求余浮点型不能进行取模运算。如果你想打印一个小数,在除法的任何一侧需要有一个浮点型的数。

C语言初阶_C语言_11

  %f是以浮点型打印a*1.0/b这个值,同上,我们把值带到%f那就可以了。这里要讲的是如果是a/b的结果是1,而是/的任一边的操作数变成浮点数(有些书也把浮点数说成实数),浮点型最后的结果就有考虑小数了,而不是像整型只考虑整数部分。(变成浮点数的过程是发生了隐式类型转换)

  操作数:操作符操作的对象就是操作数,例如a+b,+的操作数是a和b,a是左操作数,b是右操作数,因为+有两个操作数,按操作数数量给+起个名叫双目操作符。

  关系操作符:是一组指明大小关系的一组操作符有>、<、>=、<=、==、!=。==是判断是否相等,!=是判断时否不想等,如果判断为真,结果是1,判断为加,结果为0。

  单目操作符:!是逻辑反操作符,sizeof是计算变量或类型空间的小的操作符、~是按位(二进制位)取反操作符。

C语言初阶_C语言_12

  我们可以看到i是0时,!i的结果是1,i是0时,!i的结果是1。!是真变假,假变真的单目操作符。

  在计算机中,0表示假,一切非0表示真。!结果默认是0或1,意思就是如果!的操作数是0,则结果为1,如果是非0,结果为0。

  二进制与十进制:二进制的基数只有0和1,到2进位。初学者可能不太熟悉,那我们可以类比一下十进制,十进制的基数是0、1、2、3、…… 、到9,遇10进位。八进制也是十六进制也可以这样类比,需要注意的是十六进制从10开始,用字母代替,a字母对应10、b字母对应11、…… 、f字母对应15

C语言初阶_C语言_13

  十进制转二进制,二进制转十进制的练习:10110(前面的0省略)转十进制是多少?20(十进制)的二进制是多少。

C语言初阶_C语言_14

  1.2.2类型开辟内存空间的大小

  操作符sizeof(),这里不是函数,虽然有(),等等有解释,sizeof()是用来计算变量或类型的内存大小的,单位是字节(byte),一个字节是8个bit位。所以在前面说i有32个bit位意味着,i是4个字节的空间大小,话不多说,看代码:

C语言初阶_C语言_15

  char、short、int、long、float、double、分别为变量开辟了1、2、4、4、4、8字节的空间。

  补充一下计算机内存单位的知识:最小的计算机单位是bit位,然后字节,kb,mb,gb,tb。进制是1字节=8bit、1kb=1024字节、1mb=1024kb、1gb=1024mb,1tb=1024gb。可能你还没有大小的概念,其实一个bit位的大小形象讲就是存一个1或0,在内存中,要存数字1或0需要的空间就是1个bit位

C语言初阶_C语言_16

  因为sizeof a是没问题的,假设它是一个函数,调用函数必须要用(),但sizeof是个操作符,可以不用加(仅限对于变量),看到错误的地方,计算类型的大小时,()是不能省略的

  回归正传,~单目操作符是按位取反的意思,int i = 0; int j = ~i;                i的二进制位是:00000000000000000000000000000000                                j的二进制位是:11111111111111111111111111111111 如果我们打印j,j的结果会使多少?是很大很大的一个数吗,其实这里就牵涉到有符号数和无符号数,原码、反码、补码的问题了,后面讲,这里的j打印的值是-1整型在内存中存的是补码,我们写出来的原码,原码按位取反得到反码,反码+1得到补码,int是一个有符号的整型(signed) int,默认的,最高位是符号位,符号位是1表示负,是0表示正。j的补码是全1,打印的时候要转成原码,先减1得到反码,再按位取反得到原码是1000000000000000000000000000001,所以是-1啦

  移位操作符位操作符,同样的都是对二进制位进行操作。

  移位操作符有:<<左移操作符、>>右移操作符。

C语言初阶_C语言_17

    位操作符有:&按位与、|按位或、^按位异或。不得不说这个和数学的命题里的判断真假有点像。

C语言初阶_C语言_18

  逻辑操作符:&&逻辑与和||逻辑或,这对操作符不再是对二进制位下手了,看表达式结果,与数学中的并且和或者差不多的意思。

C语言初阶_C语言_19

  a是10,非0为真,b是5也为真,&&在两个操作数都为真的情况下,默认的结果是1,逻辑与只有两边都为真才是真,如果有假的话(逻辑与和逻辑或会控制表达式求值,待会讲),结果是0。而逻辑或也很简单,只有有一个结果是真,最终结果就是真,注意这里讲的逻辑与和逻辑或区别于位操作符,位操作符是对二进制位的,逻辑操作符是对结果的(5是非0,就是真,0是假),不要混淆了

  为什么说&&和并且像、||和或者像,看代码。

C语言初阶_C语言_20

  1.2.3逻辑操作符控制表达式求值

  我们再补充两个单目操作符,分别是++、--。int a = 10;a++;a的值会变成11。int b = 10;b--;b的值会变成9。这是后置++、--,放在变量后面,还有放在变量前面的是前置++、--,它们的不同在于是先使用还是先调整,请看代码:

C语言初阶_C语言_21

  补充完后,我们来看一道题,了解逻辑操作符是如何控制表达式求值的。

C语言初阶_C语言_22

  我们粗略分析一下,a++先使用后调整 也就是0 && ++b && d++; 然后接着算后面的运算,那答案就出错了,是计算机错了吗?不,计算机是不会出错的,我们要谦虚点,要么是自己打出bug了,要么就是自己分析得不对,这里是我们忽略了逻辑操作符有控制表达式求值这个点。

  正确的解析是:a++先使用,计算机算出a的值是0(为假)后无论如何结果都是假,它就没继续往下算了,到此终止,这就是短路求值,最后i被赋值0,只有a自增1,其它都不变,最后就是打印出屏幕的结果。

  如果把&&换成||,结果又是如何?换成||,当计算机遇到真的时候,就停止往下算,因为只要有真,||表达式的结果一定为真。总结来说:&&操作符遇到假就停止运算,||遇到真就停止运算,它们对表达式的值有控制作用

  赋值操作符:=、+=、-=、*=、/=、&=、|=、^=、>>=、<<=。基本赋值操作符=是来给变量赋值的,还有加等,减等、乘等、除等,是复合赋值操作符,它们其实也很简单,代码一看便知:

C语言初阶_C语言_23

  强制类型转换用(type),也是一个单目操作符,它的作用改变变量的数据类型,比如,int i = 5;(float)i;就把i的类型从int转换成float了,在C语言中经 常需要使用到强制类型转换(type),学到后面就get到了,当数据类型不相同的两个数进行操作时,编译器会报警告,因为类型不兼容。

  条件表达式,逗号表达式,以及另外几个操作符:.(点操作符)、->(箭头)、&(取地址操作符)、*(解引用操作符)我们到恰当的时候都会讲,大家看到这累了吧,休息一会吧~~,我也敲了好久。

  我们学了的和提到的单目操作符有:!、~、sizeof()、++、--、(type)、&,*。

  还有两个操作符现在可以讲,分别是[](下标引用操作符)是用于数组的、()函数调用操作符,函数调用操作符我们已经比较熟悉了。接下来我们来讲字符串和数组啦。

1.3字符串和数组

1.3.1字符串字面值

  C语言有没有字符串类型呢?答案是没有。什么是字符串,由一对双引号“”括起来的一串字符称为字符串字面值也简称为字符串,字符串的结束标志是(字符斜杠0) '\0',为了加快点进度,开始加速,请做好扶稳咯!后面多用代码来解释啦:

  补充:单独的一个“hello, world”这样一个字符串,叫做字符串字面值,在讲常量的时候,我们说3是一个常量字面值,对的,由双引号括起来的单独的一串字符是不能被修改的

C语言初阶_C语言_24

  arr3打印出bit是因为有斜杠0这个元素在数组里面,arr1打印效果与arr3一样,其实是因为“字符串”,双引号引起的字符串里隐藏了一个斜杠0,而arr2就没有斜杠0了,所以在打印的时候会一直打印下去直到遇到斜杠0才停止下来,期间我们只知道会打印bit、后面的值是随机值我们预料不到。

1.3.2数组的创建、初始化和访问

C语言初阶_C语言_25

  创建数组就是确定元素类型、起个数组名、[]看元素个数。数组初始化用{},每个元素用逗号隔开,初始化是在定义的时候赋值。

  访问数组是用下标操作符[],数组的每个元素都有对应的下标,下标从0开始

C语言初阶_C语言_26

  数组的下标的最大值是元素个数减一

1.4选择语句和循环语句

1.4.1if选择语句

  在生活中,我们总是有很多选择,简单到吃晚饭的时候,是选择吃外卖还是在学校食堂吃,当我们做出一个判断后,吃什么就确定下来了。意思就是说计算机在遇到选择结构的时候,会根据判断结果,选择性地执行。

C语言初阶_C语言_27

  if语句是一个选择语句,我们要学单独一个if、if和else、if实现多分支与switch case语句实现多分支。

C语言初阶_C语言_28

C语言初阶_C语言_29

  {}代码块可以包含多条语句,也使代码更容易看懂。

  回忆一下,计算机中,0是假,一切非0为真

1.4.2while循环语句

  日复一日,年复一年。不管风吹雨打,程序员都在敲代码提升自己,只因热爱和实现自己的价值。请看代码:

C语言初阶_C语言_30

C语言初阶_C语言_31

    心中有大厂,行稳志远!循环我们先讲这个while,后面会讲do while语句,for语句,for是最常用的一个,也会讲break,continue关键字的作用。敬请期待。

1.5函数与常见关键字

1.5.1函数基本了解

  函数是程序中非常重要的一个模块,子程序是对函数的一个描述,函数是由函数头,函数体组成的,函数头包括函数返回类型、函数名、参数列表(接收主调函数传过来的参数)。

C语言初阶_C语言_32

  函数是一个方法,它解决的问题是当我们需要将两个数相加时,我们将加法封装成一个函数,通过调用函数并把参数传给函数,它就帮我们实现加法,大大简洁了代码。

C语言初阶_C语言_33

  函数是一个相对独立的一段代码,它就是单纯帮你实现一个功能,这样就好,我们追求的函数是高内聚低耦合,一个函数实现自己的功能,尽量不要与外面的代码有重合的。

1.5.2C语言中32个关键字

  关键字是C语言固有的,不能修改,也不能自创。

C语言初阶_C语言_34

auto关键字:每个局部变量都有被auto修饰,auto int a = 0;正因为每个都有,所以省略掉了,它是自动的意思,自动创建,自动销毁。

break是跳出switch case语句和循环语句用的。

continue是循环语句使用的后面会讲。

default(默认):default字句在switch case语句中是一种默认的情况,当我们的值不符合case中的任何一个语句时,走的就是default语句,记得加上,养成好习惯。

extern关键字:用于声明外部变量,外部函数。

我们能不能使用另一个原文件里定义的变量呢?使用另一个文件里定义的函数呢?联系一下库函数要使用需要使用#include包含头文件,其实要使用变量,函数都需要声明,告诉编译器有这么个东西存在。

C语言初阶_C语言_35

C语言初阶_C语言_36

变量glo_bal定义在Add文件中,想在test.c里使用需要用extern来声明。

C语言初阶_C语言_37

函数也一样,extern 函数返回类型 函数名 (函数参数类型),声明就可以用啦。

讲到extern就不得不提static关键字:

1.static修饰局部变量,延长局部变量的生命周期。

C语言初阶_C语言_38

  实际上,当我们调试的时候,循环10次中static语句只执行一次,后面就都跳过了,没执行。

C语言初阶_C语言_39

  a静态变量只能在main{}里使用。

  2.static修饰全局变量,改变了全局变量的作用范围。

  全局变量可以通过extern声明在其它文件中使用,但在定义的时候 static int a = 10; 它就只能在定义它的文件里使用。

  3.static修饰函数,改变了函数的链接性。

  函数同上,static int Add(int x,int y)后,Add只具有内链性,不具有外链性,因此如果函数是重要的不希望被人使用的可以加上这个静态关键字。

  register:寄存器关键字,目前很少使用了,它的加在变量前面是在告诉编译器,把这个变量存到寄存器中去,但存不存是编译器根据这个变量的使用情况存的。

struct结构体关键字(晚点讲)union联合体关键字(C进阶讲),结构体非常重要

typedef关键字:类型重定义,给数据类型起个小名,叫小名也是在叫对应的数据类型。

C语言初阶_C语言_40

1.6指针和结构体

1.6.1指针的本质

  指针本质上是一个地址日常我们口中说的指针是指针变量,用来存放地址的变量。在学习指针之前我们有必要了解地址是怎么产生的。

  我们知道电脑有32位或64位机器,那么就有32根或64根地址线,每根地址线都能产生正电或负电,转换成数字信号就是0或1。那么总共有多少个组合呢,答案是2的32次方(32位),我们把每一个编号当作一个地址编号对应一个内存单元,那么问题又来了,一个内存单元大小是多少合适呢?1个bit位?还是一个字节?

C语言初阶_C语言_41

1.6.2指针变量的创建

  当我们在创建变量的时候,变量存在内存中,它的内存编号是唯一的,我们希望能用一个变量存放它的地址,因为有一天我要通过存放的地址找到它,对变量进行操作。

C语言初阶_C语言_42

  pa就是指针变量,int*是指针的类型。指针占用多少字节的空间,我们仔细一想,一个地址是由32个0或1组合成的32位,欲想存放一个地址,那是不是得4个字节才能放得下,是的,在32位机器下,指针类型创建的指针变量的大小就是4个字节,64位下是8个字节。

C语言初阶_C语言_43

C语言初阶_C语言_44

  再举个例子:char ch = ‘w’; 想要一个指针指向ch char* pc = &c;              p是pointer指针的意思。

1.6.3结构体的声明,访问

  结构体是用来描述复杂对象的好东西,结构体是由成员变量组成的,成员变量可以不止是一种数据类型。

C语言初阶_C语言_45

 

  看到这里,相信你也很累了吧,看完这篇对C语言就有大概的一个了解,这只是一个轮廓。

  希望你能有所收获,求点赞,你的点赞是我更新的动力。我的CSDN现在主要更新那边啦。

















上一篇:模拟实现字符串函数strcat和strcmp
下一篇:没有了
网友评论