C语言初阶——1初识C语言(保姆级胎教)

目录

  • 前言
  • 日志
  • 一、什么是c语言
    • 1.1C的介绍
    • 1.2语言的起源和发展
  • 二、第一个c语言程序
    • 2.1编写代码
    • 2.2程序的基本框架
    • 2.3注释
    • 2.4源文件和头文件
  • 三、数据类型
    • 3.1什么是数据类型
    • 3.2数据类型的作用
    • 3.3数据类型的分类及它的打印字符
    • 3.4数据类型使用方法
    • 3.5数据类型的大小及它细分的作用
  • 四、变量和常量
    • 4.1变量
    • 4.2常量
  • 五、字符、字符串和转义字符
    • 5.1字符
    • 5.2字符串
    • 5.3转义字符
  • 六、选择语句
  • 七、循环语句
  • 八、函数
    • 8.1函数的分类
    • 8.2函数的使用
  • 九、数组
    • 9.1一组相同类型的集合叫做数组
    • 9.2数组
    • 9.3数组的本质
  • 十、运算符(操作符)
    • 10.1算术操作符
    • 10.2移位操作符(移的是二进制数)
    • 10.3位操作符(二进制位)
    • 10.4赋值操作符
    • 10.5单目操作符
    • 10.6关系操作符
    • 10.7逻辑操作符
    • 10.8关系操作符
    • 10.9下标引用、函数调用、成员、指针
  • 十一、常见关键字
  • 十二、#define定义常量和宏
  • 十三、指针
    • 13.1内存
    • 13.2指针简述
  • 十四、结构体
    • 14.1复杂对象
    • 14.2结构体
    • 14.3结构体变量内元素的修改
  • 十五、总结


前言

作者写本篇文章旨在复习自己所学知识,并把我在这个过程中遇到的困难的将解决方法和心得分享给大家。由于作者本人还是一个刚入门的菜鸟,不可避免的会出现一些错误和观点片面的地方,非常感谢读者指正!希望大家能一同进步,成为大牛,拿到好offer。
本系列(初识C语言)只是对C语言的基础知识点过一遍,是为了能让读者和自己对C有一个初步了解。


日志

2023.3.24首发.
2023.3.25首次精修.
2023.7.11第二次修改.


一、什么是c语言

1.1C的介绍

  • C语言是人和计算机沟通的编程语言。广泛用于底层开发。
  • C/C++在TIOBE常年位居前三,是一门经久不衰的语言。它是万物(指高级语言)起源,后来的许多高级计算机语言都有它的影子。

1.2语言的起源和发展

  1. 起源——二进制语言
    早期计算机只能识别二进制语言(一种低级计算机语言)。计算机是通电的硬件设备,通电后只能识别电信号,正电(1)和负电(0)。电信号1/0排列成一串数字,具有一定意义。比如假设10001,计算机把它识别成加法。
  2. 二进制语言的缺点以及发展高级语言的原因
    要实现加法,可能是10100001,很繁琐。一段段10的含义难记。人们需要一种更简洁的计算机语言让更多的人高效方便的进行编程开发。
  3. 发展过程
    假如加法还是10100001,把它用一段字母(如ADD)来表示,不是显得更简便了吗?这就是助记符。
    助记符推演成汇编语言,编程门槛便得到了降低,但还是不够简单。为此发明了B语言,c语言/c++/java…
    发展到C及后面的语言,就是高级语言了。本质上,语言的发展是为了降低编程难度,让更多人能够去学习使用,并方便人们。C语言初阶——1初识C语言(保姆级胎教)_第1张图片
  4. C标准
    c语言–>早期不是很成熟–>成熟–>流行
    c语言发明后,很火,人人都用它。但早期C不成熟。各家公司在使用时都喜欢给它加点功能。A公司加c1,B公司加c2,但B公司用不了c1,A公司用不了c2,标准不互通。 这时的C缺少一个标准使得它在各家公司都能使用,并提供强大的功能。因此美国国家标准总局在1989年就定义了一个标准,叫ANSI C(也叫c89)。
    人们觉得方便,承认了c89。90年推出了c90(与c89相似)。后续发展中出现了c99,c11(不流行,不少编译不支持)。有了标准后,互通问题得到解决,使c更流行。

C语言初阶——1初识C语言(保姆级胎教)_第2张图片

c语言常见的编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC(VS)、Turboc等。我使用的是VS2022。


二、第一个c语言程序

2.1编写代码

  1. 创建新项目
    创建新项目->空项目->下一步->项目名称->创建
    项目名称不要使用中文、特殊字符、空格。
  2. 创建.c文件
    视图->解决方案资源管理器->右击源文件->添加->新建项->名称cpp改为.c-双击c++文件
    VS2022管理器已默认添加。
    一定要把后缀改成.c,不改极有可能出现一些莫名其妙的错误。
  3. 写代码
    创建好.c文件后,就可以写代码了。
    注意编辑好的.c文件是文本信息。.c文件+编译+链接才是可执行文件exe

2.2程序的基本框架

int main()//int是整型的意思(第3章会讲到);main:主要的。主函数,程序的入口,有且仅有一个
{
  return 0;//return:返回;返回一个值
}

main主函数,函数的入口,有且仅有一个。整个程序将从main函数开始。按f10进入调试模式,观察程序走向。
C语言初阶——1初识C语言(保姆级胎教)_第3张图片

函数只能从main开始,它是程序入口。
int main()表示int要求main函数在函数的结尾返回一个整型(任意,一般为0)。
return 0;返回一个0,恰好满足前面要返回一个整型。

2.3注释

  1. 什么是注释?
    注明解释一些难以理解的代码,它不会被编译器编译,只在源代码中显示,给程序员看的。
  2. 注释的作用
    在进行一些大型项目时,你不可能自己一个人写完所有代码。你难免要阅读他人写的代码,进行合作。如果别人写了注释的话,会大大减少你的时间。同理,你的注释对自己或他人也有作用。要懂得前人栽树后人乘凉。
  3. 注释的表达
    注释风格1(c++风格)推荐
    printf("");//斜杠后的内容就是注释
    注释风格2(早期c语言风格)不推荐
    printf("");/*注释内容*/
    可进行多行注释,不能嵌套注释,风格差。
    C语言初阶——1初识C语言(保姆级胎教)_第4张图片

嵌套注释后,(/*)只会与最近的(\*),造成出错。因此,c就采用了c++的注释风格,使得c有两种注释风格。

2.4源文件和头文件

  1. c源文件:写的代码的文件。
  2. h头文件:放在代码头部的文件。
    • 为什么要引头文件?
      使用库函数时,需要引头文件,编译器才能把它加载到你的源文件,供你使用。
      好比你借别人的铅笔,要和同学说“借一下铅笔,谢谢”。同学把文具盒借给你,你就能拿到铅笔。
    • 头文件引用方式
      c语言打招呼的方式是引头文件。
      在代码头引用。不同的库函数,头文件可能同,可能不同。就像你借铅笔和橡皮,别人借给你文具盒。借书本则需要从抽屉里拿出来。文具盒就是铅笔和橡皮的头文件,书本的头文件则是抽屉,而不是文具盒。你从文具盒中不可能拿到书本。
      语法:#include<头文件名>
  3. #include是一种预处理命令。
    在安装VS时,头文件只是放在了系统里,不在源文件。源文件不能直接使用。(<>)寻找系统的头文件,把<头文件>的内容加载到源文件。比如,教室是系统,你借同学铅笔,别人要在教室的抽屉里把文具盒拿给你。
  4. 使用方法
    printf打印函数。print打印-function函数。头文件stdio.h
    standard(标准)-input(输入)-output(输出)——标准输入输出
    C语言初阶——1初识C语言(保姆级胎教)_第5张图片

引入头文件后
C语言初阶——1初识C语言(保姆级胎教)_第6张图片

运行成功


三、数据类型

3.1什么是数据类型

计算机把数据分别归类为字符类型(键盘能键入的每一个内容),整型(正整数、负整数和0),浮点类型(小数)

3.2数据类型的作用

数据类型是用来向计算机申请空间存放内容的

3.3数据类型的分类及它的打印字符

类型 关键字 大小(字节) 打印字符
字符型 char 1 %c
短整型 short 2 %d
整型 int 4 %d
长整型 long 4/8 %d
更长的整型 long long 8 %d
单精度浮点型 float 4 %f
双精度浮点型 double 8 %lf

3.4数据类型使用方法

语法:数据类型 数据名称=该类型值;
申请一个字符类型char a='S';
申请一个整型int b=1;
申请一个单精度浮点型float c=1.2f;
1.2后面的f是表示单精度浮点的意思。
如果不加f,用float、double申请,编译器都会默认为双精度。

3.5数据类型的大小及它细分的作用

  1. sizeof计算类型或变量大小,单位字节。注意sizeof是操作符,没有头文件。
    sizeof(值)
    这里不得不牵扯到计算机单位的内容。

C语言初阶——1初识C语言(保姆级胎教)_第7张图片

1个字节(byte)=8个比特(bit)。能存储8个二进制数字。

#include
int main()
{
  int a=10;//申请一个空间,存放整型10
  printf("%d",sizeof(a));//计算a的大小,并打印结果
  printf("%d",sizeof(int));
  //%d打印整型。语法("%格式化输出",取(访问)哪里的数据打印)
  return 0;
}

C语言初阶——1初识C语言(保姆级胎教)_第8张图片

两个4,说明int类型向内存申请了4个byte的空间;
\n换行。如果没有第一个printf里的\n,44会连在一起。
2. 声明
在c语言中,你想要使用一个东西,必须声明,(同前文的库函数需要打招呼一样)
数据类型 数据名=初始值;
前面把它叫做向内存申请空间,其实也叫声明。
注意,注意,注意声明必须放在代码头。即({)下面就是所有的声明。如果你突然想到用一个值,就直接声明,但它前面有printf,会报错。(这里我不是很清楚,就当放前面就好)。C++则什么地方都可以。

int main()
{
  int a=10;//声明
  printf("%d",a);//它是可以运行的
  return 0;
}
int main()
{
  int a=10;
  printf("%d",a);//代码到这里都能运行
  int b=20;//前面有printf了,已经不属于代码块({})头部,无法运行
  printf("%d",b);//前面已经无法运行,打印不了b的值20
  return 0;
}

用sizeof来计算数据类型大小
C语言初阶——1初识C语言(保姆级胎教)_第9张图片

short短整型和int整型都可以表达整型,但大小上有区别
C语言初阶——1初识C语言(保姆级胎教)_第10张图片
特别指出由于ASCLL码,char类型本质是整型(后面讲)
long类型是4/8,c标准只规定sizeof(long)>=sizeof(int)。取决编译平台,32位是4,64位是8。(我也不知道为什么我是64位,还是4字节)


四、变量和常量

4.1变量

  1. 变量的概念
    变量:值可以变(身高、体重、薪资)。
    数据类型 变量名称=该类型值;
    C语言初阶——1初识C语言(保姆级胎教)_第11张图片
    a是可变的,叫变量。
  2. 局部变量和全局变量
  • 局部变量:定义在代码块({})内部的变量
  • 全局变量:定义在代码块({})外部的变量
int a=100;//代码块({})外,为全局变量
int main()
{
  int b=10;//代码块({})内,为局部变量
  return 0;
}
  1. 变量的作用域
  • 作用域:哪里能用哪里就是它的作用域。
  • 局部变量的作用域:在它的代码块内
    C语言初阶——1初识C语言(保姆级胎教)_第12张图片

代码运行,红圈({})内是num1的作用域。
C语言初阶——1初识C语言(保姆级胎教)_第13张图片

无法运行,因为红圈才是num1的作用域。
C语言初阶——1初识C语言(保姆级胎教)_第14张图片

把printf拷进红圈,运行了。充分说明num1作用域在红圈(小代码块)内。
C语言初阶——1初识C语言(保姆级胎教)_第15张图片

代码运行。a的作用域在红圈代码块内,绿圈代码块在红圈内,被红圈大代码块包含,自然能使用。

  • 全局变量的作用域:整个程序,包括外部文件。
  1. 变量的使用
  • scanf输入函数,用键盘键入内容(头文件string.h)
    scanf("%d",&某个变量);
  • &取地址操作符
    变量是数据类型向计算机申请空间以储存的,那么变量该放在哪里?又应该如何找到它?
    C语言初阶——1初识C语言(保姆级胎教)_第16张图片
    &只是找到地址,没有把值拿出,只是找了一个地方给你存东西。
    scanf输入的值放哪,必然要地方存。如果没有&找地方,计算机就不知道值要放到哪里。&后,计算机找到一个能存放值的空间。
  1. 声明
    c声明放代码头,c++任意。
  2. 局部变量在这里的作用
    进行加法运算,要输入两个值。scanf必不可少。
    C语言初阶——1初识C语言(保姆级胎教)_第17张图片

用scanf函数所输入的值需要用空间来存放,num1和num2作用就是向内存申请空间供scanf输入的值存放。
7. 局部变量和全局变量的名称冲突,局部优先。
C语言初阶——1初识C语言(保姆级胎教)_第18张图片

尽量不要让局部变量和全局变量名字冲突,容易产生bug
8. 使用外部全局变量
extern声明外部符号
extern 外部数据类型 外部数据名;
C语言初阶——1初识C语言(保姆级胎教)_第19张图片

同时解释了全局变量的作用域是整个程序。
9. 变量的生命周期

  • 局部变量:生命周期在作用域,进入作用域生命周期开始,出作用域生命周期结束。
  • 全局变量:整个程序。
  1. #define _CRT_SECURE_NO_WARNINGS的含义、作用
  • 含义:#define _CRT_SECURE_NO_WARNINGS定义安全无警告。
  • 作用:在VS中,使用scanf、strlen、strcpy等等函数时会报错,警告你这些函数不安全,要求使用scanf_s这种格式(后面加_s)。
    是因为scanf是c的库提供的,scanf_s是VS提供的。VS不承认c的格式。
    我们可以用VS标准,但当代码放到其他编译器时,scanf_s是错的。使代码失去可移植性(代码不加更改直接放到其他编译器里也能运行,好程序的一个标准)。在代码第一行加上#define _CRT_SECURE_NO_WARNINGS,可忽略警告。
  1. 默认储存`#define _CRT_SECURE_NO_WARNINGS``
    如果写一段代码前都加上它,这很浪费时间。所以我们可以把它默认存在编译器里。(注意#define后面有一个空格)
    首先在电脑找到这个newc++file.cpp,路径是
    Program Files/Miceosoft Visual Studio/2022/Commumity/Common7/IDE/VC/VCProjectltems
    C语言初阶——1初识C语言(保姆级胎教)_第20张图片
    用记事本打开将看到全是空白,复制粘贴放进去,往后新建源文件都会自带。
    部分人无法保存,因为文件受保护。
    绕过它的方法
    一:以管理员身份打开记事本,在记事本找文件,即可修改。
    二:把文件移动到桌面,再用记事本打开,修改之后你会发现可以保存。然后再移动回原来的地方(有替换点替换)。

4.2常量

  1. 常量:不变的量。如身份证号,血型。
  2. 常量的分类
    字面常量
    const修饰的常变量
    #define定义的标识符常量
    枚举常量
  3. 字面常量:直接写出来的数字,不能改变。如1,123,-1,-2,0都是字面常量。
    语法:直接写就出来。
  4. const修饰的常变量:把一个变量定义为常量。本质上还是变量,只是拥有了常量的属性。
    const 数据类型 数据名=值;
    无const修饰时的变量
    C语言初阶——1初识C语言(保姆级胎教)_第21张图片

const修饰后,num具备了常量的属性,不能被再次赋值。
C语言初阶——1初识C语言(保姆级胎教)_第22张图片

被const修饰的变量只是具备了常量的属性,披了常量的皮,本质上还是变量。用数组验证。
数组:一组相同类型的集合。目前只要知道表达就行。
数据类型 数组名[数组内的元素个数]={元素1,元素2,元素3……};
([])内的值必须是一个整型常量,可不写,计算机会计算([])的个数。但[]内不能是变量。当([])为变量时,报错。
C语言初阶——1初识C语言(保姆级胎教)_第23张图片
因此,我们就可以将变量放进数组([])里验证const修饰的变量的本质。
C语言初阶——1初识C语言(保姆级胎教)_第24张图片

不能运行。如果能,你的源文件多半是.cpp。
5. #define定义的标识符常量:变量被#define定义后,本质上已经变成了常量
#define 标识符 数值 (没有结尾)
C语言初阶——1初识C语言(保姆级胎教)_第25张图片

num被#define定义后放到数组arr里能运行,说明num真是常量。
6. 枚举常量:一一列举的常量,有排序。

enum 枚举名
{
  元素1,
  元素2,
  元素3
};

这些元素就叫做枚举常量
使用:enum 枚举名 变量=枚举内一个元素;
C语言初阶——1初识C语言(保姆级胎教)_第26张图片
枚举常量都有一个默认的值,这个值是从0开始一一排序的。
枚举常量不能被改变(May),被枚举常量赋值过的变量(a)不能用字面常量赋值
C语言初阶——1初识C语言(保姆级胎教)_第27张图片

但被枚举常量赋值过的变量可以被枚举常量再次赋值
C语言初阶——1初识C语言(保姆级胎教)_第28张图片


五、字符、字符串和转义字符

5.1字符

  1. 用(‘字符内容’)括起来的就叫字符,键盘上键入的内容都是字符
  2. ‘1’,'a’叫字符1,字符a。

5.2字符串

  1. 字符串:一串字符。(“字符串”)

  2. "hello worlk"
    字符串hello worlk。特殊的空字符串(“”),有时用到。

  3. 字符串结束标志:字符串后面都隐藏了一个\0。"abc"除了’a’,‘b’,‘c’之外,其实还有一个\0,真正为’a’,‘b’,‘c’,‘\0’。‘\0’作为结束标志,不算字符串内容,用来结束字符串。
    C语言初阶——1初识C语言(保姆级胎教)_第29张图片
    烫烫烫?
    因为arr1是字符串,它隐藏’\0’。'\0’让打印停止,只打印了abc。而arr2是三个字符,没有\0。打印到c时,没有遇到\0,不结束,后面打印随机。直至遇到\0,打印停止。为了直观,我给arr2加上\0试试。
    C语言初阶——1初识C语言(保姆级胎教)_第30张图片
    说明了\0是字符串结束标志,0也可以。因为0作为ASCLL码值对应字符就是\0,这里就牵扯出了ASCII码表。

  4. ASCII码表
    计算机只能储存二进制数字10。用10可以表达数字,但#\*acd及其它字符又怎么存?为此人们给字符都编了一个值,让这个值来表示对应字符。这些值就叫ASCII码值,人们把ASCll码值与字符的对应关系组成的表叫做ASCII表。
    C语言初阶——1初识C语言(保姆级胎教)_第31张图片

  5. strlen函数:string length计算字符串长度(头文件string.h),单位字节。
    strlen(值)
    \0(属转义字符)是字符串结束标志,strlen在遇到\0时会结束计算。
    C语言初阶——1初识C语言(保姆级胎教)_第32张图片
    arr1是字符串,含有\0。strlen计算abc后,遇到\0停止,\0不算内容,长度为3。而arr2不是字符串,无\0。计算完abc后,它还会计算,直到遇到\0,所以打印的是随机值,不固定。

5.3转义字符

  • 转义字符:转变原来的意思。在要转义的字符前加(\)
    假如要在屏幕上打印一个abc
    C语言初阶——1初识C语言(保姆级胎教)_第33张图片

一个printf就搞定了。但如果让你输出一个abc\n呢?
C语言初阶——1初识C语言(保姆级胎教)_第34张图片
没打印\n,因为\n是转义字符,\把n转变成换行。两图下面那段话与abc的距离不一样。后者多了一行。
打印地址c:\test\32\test.c
C语言初阶——1初识C语言(保姆级胎教)_第35张图片
\是转义字符,它后面有特定字符时,会转变原来的意思
\t是一个转义字符,相当于tab水平制表符。要打印出\t,怎么办呢?在它的前面加一个\,让\t不再是tab键,而就是一个普通的\再加个t。
C语言初阶——1初识C语言(保姆级胎教)_第36张图片
第一个\将第二个\转义成了普通\,不再是用来转义字符的\。

  • 常见转义字符
转义字符 含义
\? 在书写多个问号时使用,防止它们被解析成三字母符
\’ 用于表示字符常量’
\" 用于表示一个字符串内部的双引号
\\ 用于表示一个反斜杠,防止它被解释为一个转义序列符
\a 警告符号,蜂鸣。电脑响一下
\b 退格符
\f 进纸符
\n 换行
\r 回车
\t 水平制表符tab
\v 垂直制表符
\ddd ddd表示一个八进制数字。如:\127
\xdd dd表示2个十六进制数字。如:\x439

这里再给大家介绍几个例子。想打引一个'
C语言初阶——1初识C语言(保姆级胎教)_第37张图片
打印单个’和"时,在第二个(‘)前加个\,防止和第一个(’)配对
C语言初阶——1初识C语言(保姆级胎教)_第38张图片
打印(")也是如此。如果但印的是$,源文件可能是.cpp
用strlen计算字符串长度验证转义字符只算一个长度。
C语言初阶——1初识C语言(保姆级胎教)_第39张图片
当将两个\t和\32作为一个字符时内容的长度是13,说明转义字符只算1。
\ddd和\xdd
\ddd:一个八进制数字转换成十进制作为ASCLL码值所对应的字符。\32,它转化成十进制数字是26,对应的字符是箭头。\32其实是箭头。
C语言初阶——1初识C语言(保姆级胎教)_第40张图片
不知道为啥是方框,正常打印会是一个箭头。(欢迎解惑)
同理\xdd是16进制数字转化成十进制,以这个数值做ASCLL码值所对应的字符。
区别八进制和十六进制是看\后面有无x,没有是8,有是16。


六、选择语句

暑假时,你想去体验一把父母的不易,来到一家主打螺丝的流水线工厂。你会面临两个选择。
选项1:好好打螺丝。选项2:摆烂。
这种要选择的场景,就要用到选择语句

if(判断条件)
  语句1
else
  语句2

如果满足if的条件,则执行语句1,不满足则执行语句2
C语言初阶——1初识C语言(保姆级胎教)_第41张图片
输出0,不符合if(input==1),所以执行了else的语句。输出1,则打印出打工人。
执行语句可以有多条。超过1条,就必须把全部语句用代码块({})括起来。
C语言初阶——1初识C语言(保姆级胎教)_第42张图片


七、循环语句

有一天主管告诉你,打够100w颗螺丝,涨工资。为此你决定天天打螺丝。一天打1w颗螺丝,打了100天,月工资+2北。这就是生活中的循环。
循环语句,现在使用的是while循环(还有两种循环)。

while(循环条件)
{
  执行语句1
  执行语句2
  调整
}

C语言初阶——1初识C语言(保姆级胎教)_第43张图片

运算符+=和++
q+=1和i=q+1完成等价。q<100判断是否继续循环的条件。符合,继续循环。不符合则跳出循环。
printf是执行语句,while循环可以有多条执行语句。
q+=1和count调整。

八、函数

8.1函数的分类

库函数:c标准提供的,有固定名字,要引对应头文件。
自定义函数:自定义的函数

8.2函数的使用

库函数:printf、scanf等都是库函数,有自己的使用方法
自定义函数:自己写的函数
像在数学里
f(x)=2x
这是一个简单的函数,然而写概念题时,会给出一种概念函数(其实也就是自定义函数)
f(x,y)=2x+3y
x=1时,y=2时f(1,2)=21+32=7
这就相当于自定义函数。而你要重复使用一个超级复杂的算法时,每次都只用+-*/去实现,是不太可能的。自定义函数将减少你的工作量。

数据类型 函数名(相同数据类型 值,相同数据类型 值)
{
  定义的算法
  return 算法结果;
}

C语言初阶——1初识C语言(保姆级胎教)_第44张图片


九、数组

9.1一组相同类型的集合叫做数组

假设要声明1,2,3,4等一堆数字时,一个个声明很浪费时间。因此c语言提出了数组
数据类型 数组名[数组内元素个数]={‘元素1’,‘元素2’,‘元素3’……};
数据类型 数组名[一个值];
写有元素的数组叫初始化,初始化后,([])内的值可省略。计算机会自动识别个数。

9.2数组

数组每个元素都有一个下标,默认从0开始。
C语言初阶——1初识C语言(保姆级胎教)_第45张图片
用这个数组输出4,4对应下标3,所以用arr[3]打印。
C语言初阶——1初识C语言(保姆级胎教)_第46张图片
while循环结合数组打印出1-10。
C语言初阶——1初识C语言(保姆级胎教)_第47张图片
有些朋友可能会觉得这里i不是变量吗?为什么能放到arr的[],因为这里的i被赋值了,有一个真正的值。(其实我不知道)

9.3数组的本质

数据类型都是指数组内元素的类型,并不是数组的类型。数组本质上是地址。(数组名是数组首元素的地址)


十、运算符(操作符)

10.1算术操作符

+ - * / %(取模)
前三种就是数学上的
/除。
分为整除和浮点除。整除,只保留商。浮点除,必须保证被除数和除数至少有一个浮点数,就是数学上的除。
%取模:取余数
C语言初阶——1初识C语言(保姆级胎教)_第48张图片

10.2移位操作符(移的是二进制数)

<<左移操作符
假设我把一个值为1的变量a<<1之后,它会在1的二进制数列在整个空间左移
在这里插入图片描述
可以预见的是a(a=1)被<<1后,值变成了2。
C语言初阶——1初识C语言(保姆级胎教)_第49张图片
>>右移操作符也是如此。

10.3位操作符(二进制位)

&、^、|
&按位与操作符:全1为1,有0则0。
C语言初阶——1初识C语言(保姆级胎教)_第50张图片
其实就是在二进制位上进行数学的逻辑且运算
|按位或:有1则1,全0为0
C语言初阶——1初识C语言(保姆级胎教)_第51张图片

^按位异或操作符:相异则1,相同则0
C语言初阶——1初识C语言(保姆级胎教)_第52张图片

10.4赋值操作符

=、+=、-=、*=、/=、&=、^=、|=、<<=、>>=
=赋值符号,把一个值赋给一个变量。==才是等于的意思
C语言初阶——1初识C语言(保姆级胎教)_第53张图片
+=和后面的都叫复合操作符

10.5单目操作符

只有一个操作数的符号。
操作数:符号关系到的数字
1+2,+有两个操作数1和2,因此它是双目操作符。
c语言中表示真(默认为1)假(0)

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

!逻辑反操作
把一个数的真假类型转换。
C语言初阶——1初识C语言(保姆级胎教)_第54张图片
c语言默认真为1
C语言初阶——1初识C语言(保姆级胎教)_第55张图片
-号和+号
-1,+1对数字取负和取正,只有一个操作数,是单目操作符
&取地址操作符、*间接访问操作符(解引用操作符)在指针那章再讲
sizeof操作数的类型大小(以字节为单位)
计算变量或类型的空间大小。
计算变量时,变量的()可以省略
C语言初阶——1初识C语言(保姆级胎教)_第56张图片
这时,我还没有把11行的代码放开,当我们放开之后
C语言初阶——1初识C语言(保姆级胎教)_第57张图片
在变量a可以不加()可以看出,sizeof是一个操作符。函数的表达必须加()。
通过sizeof计算数组大小和个数
C语言初阶——1初识C语言(保姆级胎教)_第58张图片
~按(二进制)位取反符号
数据是以二进制位在计算机中储存的。~就是在二进制位进行取反,0变成1,1变成0。对0(00000000000000000000000000000000)取反再打印,它应该是什么?
C语言初阶——1初识C语言(保姆级胎教)_第59张图片
相信初学者会跟我当初一样懵逼,为什么是-1,而不是2^32-1(11111111111111111111111111111111)。
这里涉及了计算机的三码。先声明计算机只能打印原码。
符号位:有符号数(正或负)的二进制位的最高位(第一位),0为正,1为负。
原码:正数和0储存的是原码。(正数原码,补码,反码三码相同)
反码:原码符号位不变,其他按位取反得到。
补码:反码加1。(负数储存的是补码)
只要是整数,计算机储存的都是补码。
C语言初阶——1初识C语言(保姆级胎教)_第60张图片
当0被~后,符号位从0(正)变成了1(负),此时已经变成了补码存在计算机里。计算机只能打印原码,只能转化为原码-1。
–和++的前置、后置
后置++
C语言初阶——1初识C语言(保姆级胎教)_第61张图片
前置++
C语言初阶——1初识C语言(保姆级胎教)_第62张图片
前置–和后置–同上述
(类型)强制类型转换
把一种类型转换成其他类型
正常来说int a=3.14;这种声明无效。因为3.14是浮点型,不是整型。但可以通过强制类型转换把a强制转换为int。
C语言初阶——1初识C语言(保姆级胎教)_第63张图片
结果只取整数,舍弃小数点后的数。不建议这样转换,容易出bug。

10.6关系操作符

>、>=、<、<=、!=(测试“不相等”)、==(测试“相等”)
前面四个就是数学上的。!=相当于数学的≠,==相当于数学的=

10.7逻辑操作符

&&逻辑与、||逻辑或
不要和前面的&、|混淆。&、|是按(二进制)位的,而&&和||是直接计算的。
&&逻辑与:全真(1)为真,一假(0)为假、
C语言初阶——1初识C语言(保姆级胎教)_第64张图片
假如b为0(假),那么输出的就是0了。
||逻辑或:一真则真,全假为假。

10.8关系操作符

exp1?exp2:exp3;
exp1结果是真,exp2被执行。如果为假,exp3执行。
C语言初阶——1初识C语言(保姆级胎教)_第65张图片
a>b(exp1)。20>10,exp1不成立,执行exp3(b)。所以输出20。如果a为100,exp1成立,执行a,输出的是100。当然这只是一种简单用法

10.9下标引用、函数调用、成员、指针

[] () . ->
[]在数组时用到,在里面输入下标访问元素。()在使用函数用到。后两种后面讲。
逗号表达式
exp1,exp2,exp3,…expn
只要知道能隔开一个表达式就行。


十一、常见关键字

  • 自己定义的变量名和函数名不能与关键字相同,会冲突。
  • auto(自动):声明局部变量时,它进入作用域自动创建,出作用域自动销魂。因此,像int a=10; 其实省略了一个auto。auto int a=10;。只不过因为大家都有auto,因此省略不写。
  • brake(终止):主要用在循环语句和Switch语句。
  • case(实例):switch里面使用
  • char:char类型
  • const:const修饰的常变量
  • continue(继续):循环用到
  • default(默认):switch语句用到
  • do:do while循环
  • double:双精度浮点型
  • if else:选择语句
  • enum:枚举常量
  • extern:引用(声明)外部符号
    extern 数据类型 外部函数名(数据类型,数据类型);
    extern 数据类型 变量名;
  • float:单精度浮点型
  • for:for循环
  • goto:goto语句
  • int:整型
  • long:长整型
  • register:寄存器关键字
    CPU中央处理器。早期计算机运算时先从内存拿数据,内存和CPU处理数据速度相近。随着计算机的发展,CPU处理数据的速度越来越快。内存访问速度跟不上。因此,人们给计算机加上了更快的设备——寄存器和高速缓存。
    C语言初阶——1初识C语言(保姆级胎教)_第66张图片

发展到后来,CPU先从寄存器拿数据。寄存器内存小(造价昂贵),数据少。往往可能拿不到数据,寄存器会先给高速缓存和内存命令,把数据逐级传上来。等CPU拿数据时,可以给到CPU。
如果CPU从寄存器一直拿不到数据时,CPU才会向下逐级拿数据。
既然寄存器访问那么快,那么以后数据都放在寄存器不就好了?register就是把变量放在寄存器,而不是内存。但什么都放在寄存器,寄存器只有几个字节,放不下。
因此rigister的作用只是建议把数据存储在寄存器,到底是不是还要看计算机。
rigister int a=1;

  • return:返回

  • short:短整型

  • signed:有符号数
    定义变量时
    int a=10;int b=-5;
    这些都是有符号的数,因为int定义的数是有符号的。其实在int前省略了signed
    signed int a=10;signed int b=-5;
    un/signed无符号数
    和signed对应,如果一个数没有符号的话,就没有了正数之分,只会是正数(理解为绝对值就行)。即unsigned int b=-5;,b的值是5。

  • sizeof:计算大小,单位字节

  • static:静态
    C语言初阶——1初识C语言(保姆级胎教)_第67张图片
    按f10或f11进入调试模式打开监视窗口(打开方法:调试模式下 调试–窗口–监视)详细查看。最好按f11,f11才会进入test内部。
    C语言初阶——1初识C语言(保姆级胎教)_第68张图片
    第3步时,a是局部变量,进作用域生命周期开始,被打印2后出作用域,生命周期结束被销毁。然后经过下一次循环的第3步,a=1又被创建,这是一个新的a。你可以这么理解,第一次创建的是a1,第二次创建的是a2……
    5次循环后,打印了5个2。a加上一个static后,a就变成了静态局部变量。
    C语言初阶——1初识C语言(保姆级胎教)_第69张图片
    a的值得到累加,因为第一次产生的变量a1并没有像不加static那样被销毁,每次打印的都是a1。说明static修饰局部变量时,局部变量只进行一次初识化(创建那次),并且生命周期被延长了。
    static修饰全局变量
    新建一个源文件1,在里面我输入了static int AAA=99;
    C语言初阶——1初识C语言(保姆级胎教)_第70张图片
    在源文件里用extern调用AAA=99,报错。因为当static修饰全局变量时,改变了变量的作用域,让静态的全局变量只能在自己的源文件(这里AAA只能在源文件1.cpp使用)内部使用,出了源文件就无法使用。
    static修饰函数和修饰全局变量作用相同,说法不同。只要知道一个函数是有外部链接属性的(可被其他源文件用extern调用),static修饰后该函数被改变了链接属性,没有了外部链接属性,只有内部链接属性(只能在自己所在的源文件使用)。
    struct:结构体关键字(结构体那章讲)
    switch:switch语句
    typedef:类型重定义
    C语言初阶——1初识C语言(保姆级胎教)_第71张图片

  • union联合体/共用体(以后介绍)

  • void无/空

  • volatile(暂时不介绍,太难)

  • while:while循环

十二、#define定义常量和宏

#define定义标识符常量前面已讲
宏在标识符常量的基础上带上参数。
C语言初阶——1初识C语言(保姆级胎教)_第72张图片
它相较于标识符常量是有参数(X,Y)的。这就是函数和宏的区别。(感觉和函数区别也不大,可能是简洁吧)。

十三、指针

要讲清楚指针,首先要搞清楚内存。

13.1内存

内存是电脑上特别重要的存储器,计算机中所有程序的运行都是在内存中进行的。
为了有效的使用内存,就把内存划分成一个个小的内存单元。为了能够有效的访问(调用)到每个内存单元,就把内存单元进行了编号,编号也被称为该内存的地址,即编号=地址
内存的地址就当于现实生活中的身份证地址,通过它可以找到你家,而内存的地址也是如此。
C语言初阶——1初识C语言(保姆级胎教)_第73张图片
上图的二进制序列作为每一个内存块的编号,同时也是地址。而一个内存块是多大才算合适呢?假设是1个bit,那么2^32个内存亏块换算成g就有0.5g,这看起来很小。那是多少合适呢?在假设它是1个byte,那么总共有4g,这时就差不多了。

13.2指针简述

int main()
{
  int a=10;
  return 0;
}

这里向内存申请了4个字节的空间,那这4个字节放在哪里了?我想拿这个地址,就要用到&取地址操作符和*解引用操作符。
先来用&来找一个变量的地址。
C语言初阶——1初识C语言(保姆级胎教)_第74张图片
它是用16进制打印的一个地址。它其实还是一个二进制,只不过是用16进制表示方便。
这个10被我们存到了变量a里面,&a其实就是一个地址(a的地址)。那么我们能不能把它存起来。其实也是可以的,c语言只要是一个值都能存起来。那么该怎么存?比如用p来存放&a。有一种变量是专门用来存放地址的,被称为指针变量。而指针是指向这个地址的,也可以说指针=地址=编号。p就是指针变量p。

int main()
{
  int  a=10;
  int* p=&a;
  return 0;
}

int*是p的类型,p是指针变量,p里面存放的是a的地址。想要存的变量是什么类型,指针就是给该类型加个*。
C语言初阶——1初识C语言(保姆级胎教)_第75张图片
说明a地址确实被存放到了p里面。但我们仅仅是为了存起来吗?就像你的朋友把你身份证上角的地址记住,是为了未来有一天通过这个地址去到你家。
计算机也是一样。在p前面加*,这个*就是解引用操作符,通过它来解引用操作,找到它所指向的对象a,理解为*p=a
C语言初阶——1初识C语言(保姆级胎教)_第76张图片
其实就是p被*解引用成了a,a的值被赋值为20。这里还是要解释一下下面三行代码的意思。
C语言初阶——1初识C语言(保姆级胎教)_第77张图片
还要清楚的是,这里第二行的*和第三行的*的含义是不一样的。第一个*是用来说明p的类型是一个指针变量,只是一个语法形式。
而*前面用int是因为你的指针p指向的是a。a是int,p指向它,所以是int。第二个*是用来对a进行解引用,找到a。
指针的大小是4/8(32位是4,64位是8)个字节,无论指针是什么类型。
32位计算机,有32根地址线,产生32个二进制数字。一个数字对应一个bit,因此是4个字节。64位机器,8个字节。因此指针的大小不取决于指针类型,取决于计算机。

C语言初阶——1初识C语言(保姆级胎教)_第78张图片
我的计算机是64位的,是8个字节。(好像也与编译器平台有关,不是很清楚,初学者忽略这句话就好。)

十四、结构体

14.1复杂对象

计算机中的int、double类型等都是用来描述生活中的值,那么一个人该怎么表示?int?short?都不符合啊!因为人有姓名、身高、身份证等属性。在比如书,有书名、价格、作者等数学。对这些复杂对象的表示,c语言就是用结构体来解决的。

14.2结构体

自己创造出来的一种类型。用它来描述这些复杂对象的属性。

struct 复杂对象名         //struct结构体关键字
{
  属性1 元素1;
  属性2 元素2;
  ...
};//这个分号不能少,专门用来结束这个类型定义
int main()
{
  struct 复杂对象名 变量={元素1,元素2...};
}

C语言初阶——1初识C语言(保姆级胎教)_第79张图片

创建一个人a1,他的名字叫张三,身高1.8m。
假设要打印a1的名字和身高,通过(.)来访问数据
a1.namea1.stature
正常访问只需要到a1,而访问结构体元素就需要进一步打开它里面的元素。点的作用相当于打开name(我是这么理解的)
其实还可以通过指针来访问结构体元素

int main()
{
  struct people a1={"张三",1.8};
  struct people* pp=&a1;//指针pp指向的是a1,a1的类型是struct people。因此pp的类型只需要加*
  printf("姓名:%p\n",(*pp).name);//这里*pp是对pp解引用找到a1
  printf("身高:%lf\n",(*pp).stature);
}

但这种方式有点啰嗦,我们用另一个符号来表示。

int main()
{
  struct people a1={"张三",1.8};
  struct people* pp=&a1;
  printf("姓名:%p\n",pp->name);
  printf("身高:%lf\n",pp->stature);
  //.  结构体成员
  //-> 结构体指针
}

指针pp不是指向a1的吗?怎么指向,用(->)指向。
合起来的意思就是pp指向的对象a1里的name。这样的方法明显简单不少,且更直观。pp是指针嘛,用箭头指向a1。

14.3结构体变量内元素的修改

假设这个张三长高了5cm,所以有所修改
C语言初阶——1初识C语言(保姆级胎教)_第80张图片
那再假设张三突然想把名字改了叫李四,依旧如此吗?
C语言初阶——1初识C语言(保姆级胎教)_第81张图片
报错。因为stature是一个变量,它可以直接进行赋值。而name是一个数组的数组名,数组本质上是一个地址,不能修改。硬是要改,要用到一个函数。
strcpy string-copy 字符串拷贝
如果想要修改数组name的值,只能把一个新的字符串拷贝到name里。
语法strcpy(目的地,"拷贝内容");
目的地:放哪里去。拷贝内容,放进去的内容。
C语言初阶——1初识C语言(保姆级胎教)_第82张图片
成员是字符串的,它的赋值形式都需要用到strcpy。

十五、总结

先来做一个自我介绍吧。本人大一非专业生,报考的时候(爱好)就想报计科或软工的,没本事被调剂了。我专业教Python,但是我在2月初选择了万物之始的C语言。经过半个月的学习才学完这篇的知识点,这里推荐B站的鹏哥C语言,我就是看鹏哥的视频入坑的。
2. 我是2月1号开始的编程,快月底的时候电脑坏了,等修好(维修站远,开学的时候去的)已经过了差不多半个月,一天8小时以上。之后开始写这篇博客(2月底),开始的时候啥都不会,Markdown都弄了大半天(现在还是不懂)。因此摆烂了一个多星期(大家不要学我哈),后来再十多号这样子重新捡回来,又花了十天左右一点点写(新兴文科专业,太多课了),写完有花了一两天整合。虽然过程很久,但我觉得很值。在写的这个过程(费曼学习法),很多忘了的知识被重拾起来,而且印象深刻。因此,我推荐大家能够用写博客的方式学习编程。还有不要摆烂放弃。希望能与大家一起学习分享,早日成为大牛!

你可能感兴趣的:(c语言)