C语言简明入门知识

C语言的入门目录

2022/11/29|先导须知

1. 看前需知

  • 本文参考:本文先是参考了“bilibili”上的鹏哥C语言视频,然后一直在阅读《C Primer Plis(第六版)》《C和指针》《C陷阱与缺陷》(电子书其实挺好找的)在其间穿插牛客网等网站上的题目(练题挺重要的
  • 本文目标:了解C语言的基础部分,形成大概的知识网络图 本笔记只是为了在正式学习C语言之前,初步了解C语言的大致框架,仅仅只是点到为止,不会过于深入。
  • 操作系统:其他系统也可以,我的电脑操作系统是windows11,如需要下载编译器,推荐使用IDE软件:Visual studio 2022,还请下载前检查好是否合适当前的系统。

2. 内容构成

在这里插入图片描述

3. 学习时间

本人花时间学习C语言的时间比较零碎,光是C的基础关键知识就大概学了4个月(听说学C不用学那么久的?),当然学完不等于学会,现在很有学有遗漏的感觉,故写本笔记来检查自我,并且和大家一起分享学习成果。

4. 网站推荐

在学习的过程中难免会遇到一些问题,有些问题是可以依靠自己来解决的,最为常见的方法便是利用各种搜索引擎或者论坛。下面我列举几个常用的博客网站,这几个网站都是新手比较常用的,相对于直接啃食英文文档,的确会更加方便:

  1. 博客园
  2. CSDN
  3. 51CTO.com
  4. 开源中国
  5. 稀土掘金
  6. segmentfault 思否

2022/12/01

1. 驱动程序是和C语言的关系

(1)驱动程序是指驱动计算机里软件的程序,全称“设备驱动程序”,是添加到操作系统中的特殊程序,包含的有关硬件设备的。这个信息能使计算机与相应的设备进行通信;
(2)驱动程序是硬件厂商根据操作系统编写的配置文件,没有驱动程序,硬件就没有办法正常工作;
(3)电脑运行过程:(使用)应用软件->(利用)操作系统->(通过)驱动程序->(运行)硬件;
(4)操作系统的左侧的叫上层软件(C也可以运用在这里),操作系统及其右侧的叫做底层软件(C语言更加擅长底层)。

2. 计算机编程语言的发展与C语言

一个粗糙的逻辑推导
一开始直接向电脑输入二进制(还需要查手册才能写出来)
汇编语言(使用“助记符”,更好记忆语法,符合人类阅读习惯)
汇编实在是有点难用,产生了B语言(但自从被C语言取代之后,B语言几乎被废弃)
取代B语言又产生了C语言(面向过程式的计算机程序设计语言)
…后续又产生了很多优秀的语言,不过这是后话了

其中C语言逐渐完善,但是各家都是不同的标准,于是产生了C的标准。

这里推荐书籍《浪潮之巅》(作者吴军)该书主要简述了各类IT产业发展历史,是本好书,比较厚。

3. C语言的标准有什么?

目前出的C标准有很多:C89、C90、C99、C11、C17 ……还有更加新的标准,这就说明C还是流行的(因为它仍然在不断地更新),但可惜对比来说C99之前的标准更加流行,新加入的特性有的仍然未被大流所接受,因此并不是学越新的标准就越好,了解好C99之前的标准其实就很够用了。

4. 常见的编译器有哪些?如何下载一个编译器?

在这里插入图片描述

  • 在学习C语言之前,我们需要一个能写代码的环境,就像是用电脑写文章、小说一样,你必须有一个类似WPS一样的软件编写word文档吧?写代码也是一样的,需要有个编译器来写代码和运行代码
  • 但是对于新手来说,选择一个用来写代码的编译器并不容易,操作稍有不慎,就会出现各种奇怪的提示窗口。所以对于初学者来说,还是十分推荐使用IDE类型的软件(即集成开发环境)。
  • VS就是这种类型的编程软件,简单来说,编译器被包含在IDE里面,有IDE类型的软件你就可以开始写代码啦,但是以后的学习中也可以自己尝试不依赖IDE类型的软件,开始使用别的编译器试试看,不过那是后话了。
    (1)常见的有MSVC、GCC、VS、Clang、SUBLIME、WIN-TC、Turbo C;
    (2)C语言是给人看懂的,计算机只能读懂二进制,编译器把我们写的代码转化为二进制让电脑能够理解。

注意:其实VS2022应该叫集成开发环境(缩写为IDE),是编辑器、编译器(例如msvc)、调试器的集合开发。

注意:VC是个编辑器,要装插件不能独自编译;VS是集成环境(内部有编辑器、编译器、链接器),即装即用,对新手更加友好。

1、VS2019(或者VS2022)的初步了解
(1)VS的优点:VS全名是Visual Studio,它其实不是存粹的编译器,而是集成开发环境(IDE,Integrated Development Environment )一下载就可以上手,对新手友好,不需要配置太多环境,有比较美化的代码风格。(支持大概95%左右的C标准吧,以下为VS的代码片段截图);
在这里插入图片描述
(2)VS的缺点:内存占用大(新手使用其实大概需要10几G(因为如果只是为了学习C语言的话,是不需要下载VS所有的功能的),并且最好是放在C盘(预防未来出现不知名的错误),记得给自己的盘符预留好足够大的内存空间,此外还需要有良好的电脑使用习惯,不过这个事情就跑题了)。

2、为什么不选择其他编译器呢?
(1)VC6.0,是98年的编译器,已经停止更新了,老旧并且兼容性差;
(2)Dev C++,10多年前(现在2022年)就停止更新了,代码风格不美观,不利于代码风格培养;
(3)CodeBlocks,有些学校在用,都是不够主流比较小众,需要配置环境,但用着还算不错;
(4)VSCode需要配置环境(本质上是个编辑器);
(5)你是大佬就用GCC、clang学习C语言。都是这些对初学计算机小白来说挺不友好的……

注意:其实编译器只要用的足够熟悉就可以,刚开始学习C语言的时候倒也没必要多纠结,只是最好不要太过老旧……

3、VS的安装过程详解(保姆级别教学)
(1)检查自己的电脑是否合适安装VS2022
①通过快捷键“win(即那个有点像田字格的微软图标)+R”,输入cmd来打开控制台。(也可以在电脑搜索“命令提示符”或者“cmd”来找到)
在这里插入图片描述
于是电脑屏幕出现类似这样的界面
在这里插入图片描述
输入systeminfo,稍后会以文字形式展示系统信息
在这里插入图片描述
或者在控制台中输入winver,这个时候就会弹出一个窗口
在这里插入图片描述在这里插入图片描述
②进入官方对于VS2022的系统要求网站,然后进行对比
③如果想下载其他版本的VS其实也可以,功能其实也差不多。不过这里也不再详细介绍其他版本的下载了。
(2)首先用浏览器(我一直用的是微软自带的Microsoft Edge,其他也都可以)进入安装链接: VS官网,打开网址如下。
在这里插入图片描述
(3)点击上方“下载”按钮(不过点这里只能下载VS2022的),然后下载“社区版”(因为是免费的),需要其他版本的VS就需要在官网找其他版本。![在这里插入图片描述](https://img-blog.csdnimg.cn/23c41932edac43fe8a924f660565916a.png
(4)下载好安装包后,打开安装包,点击安装包即可开始下载

在这里插入图片描述
(5)进入VS下载界面
在这里插入图片描述
(6)开始下载
在这里插入图片描述
(7)界面设置(选择得当可以减少VS在电脑中的内存占比)
在这里插入图片描述
①“工作负荷”的“桌面应用与移动运用”中选择“使用C++的桌面开发”
②其中“路径”改D盘当然可以,但是最好放在C盘,避免使用不稳定
③左边的“安装详细信息”也不需要改,建议直接默认就行
④看清楚安装“要求的总空间”有多少,看自己的盘符空间够不够用
(8)开始下载,并且勾选“安装后启动”选项
在这里插入图片描述

(9)等待下载成功并且重启电脑,就可以看到会出现这样的图标(没出现也可以在电脑中直接搜索Visual Studio2022)
VS2022
(10)社区版登录后VS就是完全免费的(不登陆免费30天)
在这里插入图片描述
创建一个账户就可以。
(11)“开发设置”和“选择主题颜色“
①开发设置:改成“Visual C++”即可
②颜色主题:看个人的喜好就行(个人推荐深色,不伤眼…)在这里插入图片描述
(12)点击“启动Visual Studio(S)”按钮
(13)等待初次启动完毕后,开始写第一个C语言文件

  • ①点击“创建新项目”在这里插入图片描述
  • ②搜索“空项目”,并点击“空项目”,然后点击“下一步”
    在这里插入图片描述
  • ③更改“项目的名称”(尽量英文)和“路径”(要保证自己找得到就行,比如创建一个文件夹,以后一直都放在这个文件夹里,这一次演示的话可以暂时放在“桌面”上)
    在这里插入图片描述
  • ④进入VS的界面
    在这里插入图片描述
  • ⑤右击右侧“解决方案资源管理器”中的“源文件”,点击“添加”,选择“新建项”,添加一个源文件(即后缀为.c的文件)。另外,由于我的VS装了一些小插件,所以才有“清理已选代码”这一选项,刚下载的VS是没有这个选项的,这些拓展插件以后在别的文章里面也会简单介绍几个。
    在这里插入图片描述
  • ⑥选择“C++文件”修改头文件后缀.cpp为.c(这是因为“.cpp”文件是用于C++的“.c”文件是用于C语言的)。并且修改该头文件的名字,例如我就用了main作为源文件的名字(想叫其他名字的也可以的,但同样最好是英文名字)
    在这里插入图片描述
  • ⑦工作区出现行号和光标,可以开始编写第一段代码啦!
    在这里插入图片描述
    以下是上述代码片段,可以复制下来运行试试(先别着急理解)
#include<stdio.h>
int main()
{
	printf("hello word");
	return 0;
}
  • ⑧运行程序
    Ⅰ点击F5或者fn+F5或者fn+shift+F5等(不同电脑可能快捷键不一样)运行程序
    Ⅱ也可以点击VS界面最上方的“绿色播放键”按钮,就可以运行程序
    在这里插入图片描述
  • ⑨运行结果显示
    (如果出现一闪而过的问题,可以往后看“06. 在VS2022中运行程序以及可能出现的问题”,有解决方案)
    在这里插入图片描述
  • ⑩程序运行完后,按任意键可以关闭程序(即现在跳出来的窗口),当然除了一些比较特殊的按键,比如“关机键”什么的 ……按个空格什么的就行了啦!

注意:如果一直不能下载:
1、请检查当前的网络环境是否稳定
2、修改电脑Wi-Fi里的DNS服务地址8.8.8.8或者8.8.8.4
3、虚心学习,请教身边的大佬们吧!

05. 初步认识头文件与源文件

首先从文件的后缀就可以看出来两个文件的区别:“XXX.h”叫做“头文件”,“XXX.c”叫做“源文件”,之前在VS2022里面创建的main.c就是一个源文件,现在暂时可以不知道这两者的区别,一般写一些基础的代码在.c文件中就足够了。

06. 在VS2022中运行程序以及可能出现的问题

(1)在VS中编译+链接+运行(可使用快捷键F5/fn+F5/ctrl+fn+F5,不同的电脑可能不太一样)来运行代码;
(2)若出现运行窗口一闪而过的问题,则可以:鼠标右击“项目”->“链接器”->“子系统”->修改为“控制台”即可

07. 主函数mian()的介绍

#include<stdio.h>
int main()
{
	printf("hello word");
	return 0;
}

(1)在运行第一个C程序的时候,会发现程序里有int main()

main函数是整个程序的入口,必须有且只有一个。无论是哪个C程序,第一步总是从这里开始。

注意:这个main和之前创建的.c源文件的名字“main”不一样,这里指的main是一个函数,上文那个“main”只是我给文件起的一个名字而已……

(2)有关mian函数的写法:

//第一种:常见的写法(比较多)
int main()
{
	return 0;
}
//第二种:过于古老了,建议别用
void main()
{
	return 0;
}
//第三种:也可以(很少写)
int main(int argc,char* argv[])
{
	return 0;
}
//第四种:也可以
int main(void)
{
	return 0;
}

08. 标准头文件

#include<stdio.h>
int main()
{
	printf("hello word");
	return 0;
}

在运行第一个C程序的时候会发现,开头有一个#include<stdio.h>。即标准头文件。标准头文件其实就是包含了C标准中定义的可以直接用的库函数,引用这个标准库,才可以使用printf函数。

就可以形象比喻成:我们要用别人的东西(想用标准头文件stdio.h里面放的函数printf函数),需要我们和别人打个招呼(写#include<stdio.h>),才可以使用别人的东西(使用printf函数)

注意:其中#include<stdio.h>中
①include其实是“包含”的意思
②stdio就是“标准输入输出(standard input/output)”的缩写

09. 数据类型

(1)为什么会有数据类型?

写代码
为什么写代码->
解决生活的问题->
需要信息转化为数据,利用数据描述信息->
有了数据类型的产生->
因此有能力针对数据来解决现实问题

(2)对生活中不同的数据进行分类:

类型名字
char字符类型
short短整形
int整形
long长整型
long long更长的整型
float单精度浮点型
double双精度浮点数
(3)之所以叫浮点数,是因为可以给小数*10^n对小数点进行移动。

注意:C语言标准规定long只需要保证>=(大于等于)int既可以,但是long long一定大于int;

注意:使用不同的类型的好处:空间可以节省很多,效率也能提高,但是相应的错误也会变多……
(4)运用“数据类型”来“存储数据”

#include <stdio.h>
int main()
{

	int a=10;//整形可以存储一个整数
	char b='C'//字符型可以存储一个字符(字符包括“字母”和“数字”和“特殊符号”)
	float c=3.14//浮点型可以存储一个小数

	return 0;
}

在上述代码中:整形10被存储在一个叫做a的空间里,字符C被存储在叫做b的空间里,小数3.14被存储在叫做c的空间里。

10. sizeof()的使用

sizeof()函数以字节为单位,是计算类型大小的运算符(操作符)。

#include<stdio.h>
int main()
{
	printf("%d",sizeof(int))return 0;
}
//一般打印出来4,少部分平台为2

11. 计算数据大小的单位

数据单位转化关系
Byte字节1B=8bit
Kilobyte 千字节1KB =1024B
Mega byte 兆字节 简称“兆”1MB =1024KB
Giga byte 吉字节 又称“千兆”1GB=1024MB
Tera byte 万亿字节 太字节1TB =1024GB
Peta byte 千万亿字节 拍字节1PB=1024TB
Exa byte 百亿亿字节 艾字节1EB=1024PB
Zetta byte 十万亿亿字节 泽字节1ZB = 1024 EB
Yotta byte 一亿亿亿字节 尧字节1YB= 1024 ZB
Bronto byte 一千亿亿亿字节1BB= 1024 YB
Nona byte1NB= 1024BB
Dogga byte1DB= 1024NB

注意:其中比较常用的是bit、B、KB、MB、GB、TB。后来也出现了一些简化表达,例如K有时候代表1024,M代表1024K。

12. 变量和常量的简单介绍

(1)变量的概念
①定义变量:“(类型)+(变量名/标识符)=(数据)"

int num=10;
num=20;

在后面令num=20,可以使得num的值从10变化为20,所以num就是变量
②“局部变量”和“全局变量”的区分:在{}外面的是全局变量,{}内的叫局部变量,若是存在一个变量既有全局定义和局部定义,则形成冲突,优先使用局部变量
③对于定义变量的解读
“int num=20;”中的num就是标识符,整体代码大概意思是:在电脑的空间之中,申请4个字节存放20这个数据。

注意:char ch=‘b’,只能放一个字节,而汉字有两个字节不能存放在char类型中,但是可以理解为字符串来存放

#include<stdio.h>
int num=100;
int main()
{
	int num=10;
	printf("%s",num);
	return 0;
}//则优先输出10,而非100

(2)常量的概念:值不可以改变的量。

13. scanf()的使用

scanf()是输入函数,按照指定格式取出后面变量的地址来进行输入。

注意,小数默认为double类型,所以可以在小数后面加上f或者F表明是一个float的小数;
注意,使用未初始的类型容易出错,有的老编译器是不会判断错误的,所以使用初始化是一种好的编程习惯;
注意,变量名字必须由字母、数字、下划线“_”组成,并且长度不能超过63个字符,严格区分大小写,不能是已使用的关键字,并且最好命名是有意义的

14. printf()的使用

printf()是输c出函数,按照指定格式输出后面变量的值。

2022/12/03

01、修改VS外观和字体

首先,打开VS工具->选项->环境
在这里插入图片描述
(1)在“常规->颜色主题”里改变外观
在这里插入图片描述
(2)在“字体和颜色->字体”中改变字体等
在这里插入图片描述

02、变量的作用域和生命

(1)作用域:变量的作用范围
①局部变量作用域是变量所在的局部范围(其实就是一对{}以内);
②全局变量在一个工程(利用extern可以声明全局变量为外部变量,在项目里面的不同源文件里都可以使用),但是不够安全,容易改变值,引起bug。
(2)生命周期:就是生成变量和销毁变量的一个时间段。
①在运行中,局部变量被使用了,使用完就会被销毁,也就是说局部变量的生命周期:进入作用域生命周期开始,离开作用域生命周期结束;

#include<stdio.h>
int main()//局部变量的生命周期演示
{
    {
        int a=10;//在代码块{}里面创建了a这个局部变量
        printf("%d\n",a);//这里成功打印了a的值
    }//出了代码块{}的范围,a被销毁
    printf("%d\n",a);//在上面a的值被销毁,这次就不能再输出10了
    return 0;
}

②在运行中,全局变量的“生命周期”和“整个main()开始直到运行结束”或者“整个程序的开始到运行”是一样的,也就是说全局变量的生命周期是整个程序。

03、C语言的四种常量

(1)常见的四种常量

  1. 字面常量
  2. const 修饰的常变量
  3. #define定义的标识符常量
  4. 枚举常量,关键字是enum

(2)尝试使用四种常量

#include<stdio.h>
#define MAX 100             
//#define定义的标识符常量,后面使用MAX结束后,编译过程MAX全部被替换成100,末尾不加“;”是因为容易出bug。

//以下创建了一个枚举常量,只能枚举出离散变量,但是连续变量就不能被枚举出来
enum Sex
{
    MALE,     //默认值为0
    FEMALE,   //默认值为1
    SECRET    //默认值为2
};//若是将MALE赋值为5,则后面就依次改为6、7,这叫初始化,不是改变值,所以说是常量非变量

int main()
{
    100;                    //这里只是写出字面常量,顾名思义“从字面上就可以看出来”
    'W';
    3.14;
    int a=1;                //在这里1就是常量
    
    int num_1=10;           //const 修饰的常变量
    num_1=20;               //num_1是变量,值从10变成20
    const int num_2=10;
    num_2=20;               //使用了const关键字后,这里就会报错! 
    /*如果加上前缀const,就使得变量具有了常属性,就不能被改变了,但是本质上还是个变量,只是从语法的层面给num_2“上锁”了而已*/
    /*证明,利用数组[]内不可以放变量的特点(除去新加的变长数组的情况)*/
    int arr_1[num_2]={0};  
//在C99之前,有的编译器依旧是不能运行的,这就证明了被修饰的num_2本质上还是一个变量

    int arr_2[MAX]={0};     //可以运行,这也同样证明了符号MAX是常量
    
    enum Sex s=FEMALE;
    printf("%d",s);         //输出1
    return 0;
}

04、字符、字符串和转义字符

(1)C语言表示字符由‘ ’引起,例如:‘w’;
(2)字符串由“ ”引起,例如:“abc”,“abc”会自动在末尾加上\0,\0表示“结束标志”;

注意:“a”和‘a’是有区别的,区别在于前者有\0结尾,后者则没有!

#include<stdio.h>
int main()
{
	char*="abcd";               //char*和char arr[]可以存放一个字符串,存放字符串的演示
	char arr_0[]="abcd";

	char arr_1[]={'a','b','c'};     //则打印可能会打印出abc和其他乱码,原因是后面没有\0可以结束
	printf("%s\n",arr);             //这里%s打印出字符串,但是没有\0提示结束
	char arr_2[]={'a','b','c','\0'} //这样就没问题了

	printf("%d",strlen(arr_0));     //也是靠\0来计算字符串的长度的,输出了4,即字符串的长度
	printf("%d",strlen(arr_1));     //则输出来是非3的值,是个随机值,什么时候找到\0就输出长度
	return 0;
}

(3)转义字符
①常见的有:

转义字符含义
\?问号
\ ’单引号
\ "双引号
\ \斜杠
\n换行
\t水平制表符
\v垂直制表符
\b退格符,相当于backspace
\f换页
\r回车
\dddddd表示八进制
\xdddd表示十六进制

②早期的编译器有三字母词概念,例如“??)代表]”,?是用在来转义的(类似想打印",不能直接写",而是要写\")现在的话\?比较少用了。

#include<stdio.h>
int main()
{
	printf("(are you ok??)");//由于三字母词的存在,打印出(are you ok]

	//因此利用\?就可以正常打印
	printf("(are you ok\?\?)");
	//正常打印(are you ok??)

	printf(""");   //打印失败
	printf("\"");  //就可以打印出单个"
	return 0;
}

③利用转义字符 \ 来使用ASCII码值表

#include<stdio.h>
int main()
{
	printf("%c\n",'\130');     //输出X,其中\130是八进制数字,用''引转义字符,说明本质上还是个字符,需要用''引用
	printf("%c\n",'\x63');     //输出c,其中\x63是十六进制的数字
	return 0
}
//转义字符也算字符是会被整体计算成一个字符,因此用strlen要格外注意,转义字符会整体计算进去

05、注释的使用

(1)注释有两种:

//注释1,实际上是C++的注释风格,后面被加到C中了,推荐使用这种
/*注释2,C语言的注释风格*/

(2)注释的作用:
①可以给别人看懂自己的代码,或者给未来的自己看懂自己的代码
②可以屏蔽掉不想用但是舍不得删除的代码,保留代码的同时不影响其他程序
因此注释是一个很好的习惯!
(3)另外,在VS中有关注释的快捷键为:ctrl+K/ctrl+C添加注释,ctrl+K/ctrl+U取消注释,可能不同编译器不一样)。也可以按住工具栏里的按钮实现快速注释(一般这里是有快捷键提示的,建议好好熟练快捷键)
在这里插入图片描述

2022/12/05

01、细谈scanf()的返回值

(1)scanf的返回值有三种情况

①正常返回的话就是读取到数据的个数;
②如果scanf没有读取到任何项(比如scanf需要读取一个数字而用户却输入了字母)就会返回0;
③scanf检测到“文件结尾”时就会返回EOF,而通常EOF的值是-1。
注意:使用scanf输入的时候,需要按下回车键(enter)来提示电脑你已经输入数据,不要傻傻等着光标跳动,计算机是不会自动把值输入的!

#include<stdio.h>
int main()
{
	int a=0;//存放输入值1
	int b=0;//存放输入值2
	int c=0;//存放scanf的返回值
	scanf("%d%d",&a,&b);//这里的%d的写法,就是要求是输入一个整型,如果你输入一个字母进去就会造成读取失败,返回0)
	printf("%d\n",c);
	return 0;
}

(2)在VS2022中使用scanf常常会报警告,“scanf的返回值被忽略”,其实是在提示我们要注意用上scanf的返回值,但是其实目前是可以忽略这个警告的,编译器只是警告你:要注意scanf的返回值,不要轻易忽略。
(3)利用返回值(EOF或者某个数值)来多次输入(多组输入),可以利用scanf的返回值来实现多次的输入

#include <stdio.h>
int main()
{
	int a=0;
	while(scanf("%d",&a)==1)
	{
		printf("你成功输入了%d次\n",a+1);
	}//这样就可以重复的输入了
	return 0;
}

(4)另外,VS的报错窗口就是“错误列表”,可以通过“视图”里面找到“错误列表”就可弹出。
在这里插入图片描述
在这里插入图片描述

注意:要经常看这个错误列表,能够检查出一些代码的错误。当然有的时候编译器自己也看不出来一些错误,比如,将开头main写成mian,在VS2022中,编译器也检查不出来这样的错误(只会编译失败)。

02、浮点数的四舍五入

浮点数的四舍五入是很复杂的事情,因为浮点数是不精确的值。所以在以后的条件判断中,尽量少用浮点数进行判断(容易发生误判)。

03、printf的返回值

首先看一段比较有趣的代码:

#include<stdio.h>
int main()
{
    int A=43;
    printf("%d\n",printf("%d",printf("%d",A)));
}//结果会输出什么呢?
//答案是4321

printf的返回值就是输出的字符数量

①第三个printf输出"43"字符数量为2,于是返回值为2,第二个printf就输出"2”
②第二个printf输出"2"字符数量为1,于是返回值为1,第一个printf就输出"1"
要注意一点是:返回值是是输出的字符数量,包括数字,字母,标点符号,空格,转义字符等。

#include<stdio.h>
int main()
{
    printf("%d\n",printf("0,1,2,3\n"));
}
//结果为
//0,1,2,3
//8

04、配置文件

VS保存好写好的代码后,就会多出一些配置文件,可以暂时忽略其他文件,只需关注.sln和.c和.obj和.exe就可以。(其中sln文件可以打开所有上次编辑的完整的VS文件;c文件是你自己创建的源文件;obj文件时目标文件,了解即可;exe是可执行文件,了解即可。),以下是我创建的一个项目文件。在这里插入图片描述

05、函数的概念

  • 结构:一个函数应该由函数返回值、函数名、函数参数(参数列表)、函数体构成
  • 分类:可以分为库函数(已经写好内部代码的函数,比如使用printf())和自定义函数(比如自己写一个自定义的函数Add())
  • 之所以会有函数的概念,其中几个目的是为减少代码量、更加清晰地识别代码,一个设计好的函数,我们要做某些事情的时候,只需用这个函数就行,而不必每次都去写这个函数里面的内容。

就好像,你要吃薯片,虽然可以自己做薯片,但是你可以直接买商店的包装薯片,而不必每次都自己去做。而函数就可以类比那些帮你包装好薯片的加工厂。

  • 自定义函数的结构

①无需返回的函数(无返回值的函数)

void f1(int x)//f1是由自己命名的
{
	printf("%d %d %d",x,x,x);
}//这个函数的效果就是:输入一个整数,就会自动打印三次这个整数

②需要返回的函数(有返回值的函数)

int Add(int x,int y)//2、x,y将a,b的值拷贝过来
{
    return x+y;
}//3、开始进行加法运算,并且函数返回这个加法后的值,return可以理解为等号“==”(C语言的等号是==,赋值符号是=)

int main()//0、首先从这里开始按照数字的顺序看起
{
    int a=0,b=0,c=0;
    scanf("%d%d",&a,&b);
    c=Add(a,b);//1、a,b的值被函数调用,返回值赋值给了c
    printf("%d",c);//4、打印结果c就可
    return 0;
}

06、(一维)数组的概念(英文array)

(1)概念:同时存放一组相同类型的变量。数组的存在可以不用一个一个的区定义多个变量。
(2)格式:元素类型+数组名+[元素个数]={元素};

int main()
{
	int arr[3]={0};//数组的初始化,和int a=0;这种单个变量初始化是类似的
	int arr_1[4]={1,2,3};//不完全初始化
	char arr_3[]="bit";//存放字符串
	return 0}

注意:数组是没有\0来结尾的,只有字符串才有!!!

(3)如果需要取出数组里单个的元素:利用数组的下标,从0开始,可以用下标访问一个元素

int main()
{
    int i=0
    int arr[3]={5,4,3};
    printf("%d",arr[1]);
    //输出4
    //因此可以利用循环来输出arr的所有元素
    while(i<3)
    {
        printf("%d\n",arr[i]);
    }
    return 0;
}//依次输出
//5
//4
//3

(4)事实上还有多维数组的概念,只不过本笔记暂时只介绍一维数组,后续还会写二阶数组等深入的内容。

07、操作符(运算符)

  • (1)C语言很灵活,操作符也有很多(难点之一:操作运算符的使用)。

  • 算术操作符:+、-、*、/、%

  • 移位操作符:>>、<<

  • 按位操作符:&、^、|(按位与、按位异或、按位或)

  • 赋值操作符:=、+=、-=、*=、/=、&=、^=、|=、>>=、<<

  • 单目操作符:!、-(符号)、+(符号)、&、sizeof、~、–、++

  • 关系操作符:==、>=、<=、!=

  • 逻辑操作符:&&、||

  • 条件操作符:exp1?exp2:exp3

  • 逗号操作符:exp1,exp2,exp3,……

  • 下标引用、函数调用和结构成员:[ ]、( )、.、->

注意1:%是取余数,例如1%3=3,4%3=1,5%2=1(实际上%是个比较麻烦的操作符,如果两侧都是正数,那还好理解,但是如果是负数呢?后续会进行讲解的……)

注意2:如果输出符号为%d,a/b得到的是整数,a%b得到的是余数。

注意3:/的左右只要有一个数是浮点数,就会执行浮点数运算(还有输出格式要写成%f)
另外,如果两端都是整数,那么运行结果也只会是整数,哪怕用%f输出也是一样的 注意:用/要得到完整的小数直接用用%f就行。

注意4:另外%左右应该都是整数,并且%运算后是不可以用%f输出的 注意:初始化(int a=0)和赋值(a=20)是两个概念

注意5:非零值为真,包括负数。

注意6:直接写18<=a<=30语法没问题,都是写法是错误的应该写成a>=18&&a<=30,不然是报错的

注意7:sizeof应该是属于运算符,而不是函数哦!

注意8:实际上()经常被人忽略,它又叫函数调用操作符。最大的用处就是标识一个函数

注意9:[ ]主要的作用就是利用数组的下标来访问数组的各个元素,Add(a,b)中,( )的操作对象是Add、a、b

注意10:.和->是属于结构体知识的

注意11:位操作符涉及到二进制和三码(原反补)的概念,后续会讲解

注意12:注意:后置++(–)和前置++(–)的区别

注意13:逻辑操作符&&和||的短路的性质

(2)单目操作符、双目操作符、三目操作符的区别:有多少个操作数就是几目操作符,如1+2,+操作1和2两个操作数。

08、代码风格

(1)代码高亮:关键字、函数等会有颜色区分
(2)tab的使用,好的编译器软件会自动帮你tab,会自动把代码排版好。

09、strlen的用法注意

char arr[4]={'b','i','t'};
strlen(arr);//由于放入了3个元素,第4个初始化默认为0,即'\0',故strlen(arr)是3,而不是随机值

10、学习C语言的网站

cplusplus.com但是是全英文的……可以自己尝试翻译一下,个人比较喜欢使用旧版本的网站,比较习惯。

11、注意C语言的代码和数学写法的区别

(1)等号
数学里的等于是“=”,在C语言的等于是“==”,而“=”只是一个赋值运算符
(2)大于(小于)等于号
数学里“1≤x≤2”,但在C语言里面必须要写成“(x>=1)&&(x<=2)”
(3)乘法
数学里面“3x”表示“3x”,但是在C语言里面就必须写成“3x”,不能省略乘号,只是写成“3x”,这样写编译器是会报错的

12、VS的基础调试

  • 有关的调试用法:
    ①利用printf()函数进行调试
    ②VS自带的调试功能
  • 如果能够试着调试自己的代码,就能减少代码中的bug

13、“真”与“假”的表达方式

在C语言中,数值非0的为真(包括负数),0则为假。

2022/12/07

01、三目操作符的使用(C语言里只有一个操作符)

(1)三目操作符的书写形式

(exp1?exp2:exp3)

(2)使用解说:
若是exp1为真,整个表达式的结果为exp2;
若是exp1为假,整个表达式的结果为exp3。

注意:条件操作符不要写的过于复杂,这涉及到操作符的优先级和结合性的问题

02、逗号表达式

(1)逗号表达式的书写形式

(exp_1,exp_2,exp_3,exp_4,exp_5,exp_6…,exp_n)

(2)使用解说:
从左往右算,则最后一个表达式exp_n的值为整个式子的值。

//例如:
#include <stdio.h>
int main()
{
    int a=1,b=1,c=1;
    int x=(a+1,b+2,c+2);
    printf("%d",x);
    return 0;
}

03、一些常见的关键字(常用的)

(1)关键字,相当于是英语中的词汇
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、typedf、union、unsigned、void、volatile、while
(2)这些关键字可以先稍微拓展学习一下,下面会尝试讲几个关键字的用法。
(3)在以后的学习中需要熟记这些关键字(实际上敲多了就记住了,本人英语挺不好的,也是靠不断的敲击记忆的……)
(4)不能拿关键字创建变量的名字,否则会命名冲突

04、“计算机存储的方式”和“register的作用”

(1)早期都是CPU处理,都是随着发展CPU处理速度过快了,于是有了更快的存储设备,比如寄存器,计算机的存储设备:网盘->硬盘->内存->高速缓存->寄存器
(2)不同的存储器:造价逐渐变贵,内存逐渐变小(节省电脑造价),速度逐渐变快。存储器这样类似金字塔的结构设计,使得电脑性价大大提高
于是关键字register int num=10会让编译器检查这个变量是否频繁使用,若是就把这个变量放入寄存器中,于是程序运行就会比较快(实际上在一些编译器中就算没有写这个关键字,也会自动检查哪个变量是最常用的,然后将这个变量放到寄存器中,所以有的时候选好编译器确实是比较讲究的问题)
(3)这涉及到“局部性原理”的知识后期有兴趣的可以后期看《深入理解计算机系统》初学者的话暂且别看。

05、使用“typedef”重命名

(1)使用方法

unsigned int num_1 =100;
typedef unsigned int num uint;
unit num_2=10;

(2)假设你的名字全称是“欧阳李四”,你村里的人却叫你小名“狗蛋”。这就相当于起了“别名”,故typedef的作用就像是给一些类型起了个“别名”。(你的邻居叫“狗蛋”是为了方便,而typedef的使用也是为了方便)

06、从C语言视角的内存分类和static的作用

(1)从C语言的角度来说,内存的分布可以暂时简化为
栈区:局部变量、形式参数
堆区:动态内存分配(像maiioc、calloc、realloc free等动态内存分配函数就是在这个地方被使用)
静态区:静态变量、全局变量(静态区里的东西,整个程序结束才会销毁)
(2)static(静态)的作用
①修饰局部变量

void test()
{
    int a=1;
    a++;
    printf(""%d",a);
}
int main()
{
    int i=0;
    while(i<10)
    {
        test();
        i++;
    }
    return 0;
}//这打印了10个2,也就是2 2 2 2 2 2 2 2 2 2

void test()
{
    static int a=1;//增加了static
    a++;
    printf(""%d",a);
}
int main()
{
    int i=0;
    while(i<10)
    {
        test();
        i++;
    }
    return 0;
}//这就打印了2 3 4 5 6 7 8 9 10 11,说明上面的a的值没有被销毁,仍然保留着上一次a的值

①加了static就相当于:你在做数学试卷,被老师叫去谈话,当你回来的时候,继续往下做题,没有必要重新从第一题开始
②不加static就相当于:你在做数学试卷,被老师叫去谈话,当你回来的时候,又从头开始做题了。

注意:一个局部变量本来放在栈区,加了static修饰的局部变量,就会放在静态区了,存储位置发生变化,导致局部变量出了作用域不会被销毁,改变了变量的使用周期(即存储位置发生了变化)

注意:被static修饰后,这个a后面就不会重新创建为a=1了(但是a的值是可以再被改变的,只是每次都不会被重新创建a,静态和常量不是一个概念!!!)。
注意:静态变量和全局变量还是有很大区别的!静态变量只会在被修饰的局部变量里面值不变,而全局变量整个程序都是适用的。

②修饰全局变量
使得全局变量只能在本源文件里面使用,同时能让其他源文件里,另外一个被extern修饰的全局变量跨文件作用失效。(让全局变量的外部链接属性消失了)。其实这样的话就有对这个变量进行隐藏的功能(不会被别人看到,有保密效果)

//源文件1
extern int a;
printf("%d",a);//打印不出a的值

//源文件2
static int a=10//则只能在本源文件里使用

③修饰函数

//在main_1.c中
int Add(int x,int y)
{
    return (x+y);
}

//在main_2.c中
extern int Add(int x,int y);//没有extern的时候,有的编译器是不会去调用别的头文件里面定义的函数的
int main()
{
    int a=10,b=20,sum;
    sum=Add(a,b);
    printf("%d\n",sum);
    return 0;
}

实际上在C++里面static还有两种用法,所以实际上是有五种用法

07、extern的作用

(1)可以跨.c文件使用一个被extern修饰的变量extern int num=1;
另外函数也可以类似使用:以下是两个源文件里的内容

int Add(int x,int y)
{
    return x+y;
}
exterp int Add(int,int)//这里是函数的声明,只需要告知函数的参数是什么即可
{
    int a=10,b=20;
    int sum=Add(a,b);
    printf("%d\n",sum);
    return 0;
}

(2)与static的使用同时出现时,会让extern的作用会消失

08、“#define定义常量”和“宏的使用”

(1)#define的使用

#define M 100
#define STR "hello bit"
int main()
{
    printf("%d\n",M);
    printf("%s\n",STR);
}//就会分别输出100和hello bit

(2)宏的使用

#define MAX(x,y) (x>y?x:y)//包括宏参(宏参是没有类型的),宏内容。
//宏与函数是有去区别的
int main()
{
    int a=10,b=20;
    int m=MAX(a,b);
    printf("%d\n",m);
    return 0;
}

09、指针

注意:C语言基础的重点部分,甚至有的人会出现“晕针”的现象,这一部分在之后的学习中请务必认真!!!

(1)学指针之前首先要理解一点内存的基本概念概念:内存是电脑上特别重要的存储器,看可以cun,计算机中程序的运行都是在内存中运行的,内存可以被分割成一个个“小内存”,这个“小内存”可以用一个小格子表示,每个格子有一个对应的编号,就可以依靠编号来快速找到这个格子(也就是单个的内存空间)。而这个编号就是内存的地址,这个“小内存”就叫内存单元,内存单元一般可以存放一个字节的数据(刚好放一个char类型的数据)
(2)地址的产生:32位电脑,32根地址线(相当于电线),电线是通电的,有高电平,低电平,转化为数字信号就是1或者0,32个二进制位就可以产生232个位置,能够产生232个地址(管理2^32字节的空间,其实也就4G大小的空间)
注意:64位也可以类似理解
(3)此时就可以深刻理解int a=10的含义:向内存申请4个字节的空间,存储10这个值(具体怎么存放后期讲)
▢▢▢▢▢▢▢▢|▢▢▢▢▢▢▢▢ ▢▢▢▢▢▢▢▢|▢▢▢▢▢▢▢▢ (而每个字节都有地址)
a实际上是占用4个字节的空间,但是每个字节都有地址,&a取得其实是第一个字节的地址(也就是最小的地址)
(4)int pa =&a中,取出来a的地址存放到pa,pa就是一个存放指针的变量它的类型是int,我们把pa叫做一个指针变量。

注意:*在表明pa是指针变量,int是在说明pa指向的对象是int类型。 注意:指针即“地址”,通过地址可以找到变量的值,甚至改变变量的值

注意:定义指针时,*跟在类型还是跟在变量上都可以 注意:%p是用来专门打印地址的

(5)当然指针变量本身也是一个变量
(6)那么指针变量本身的大小是多少个字节呢? 指针变量是存放地址的,地址是:
①32位机器上:32个0/1组成的2进制序列,需要32位bit位的空间存储,指针变量就需要4个字节
②64位机器上:64个0/1组成的2进制序列,需要64位bit位的空间存储,指针变量就需要8个字节(编译器可以换位数)

int main()
{
    char* p1;
    int* p2;
    double *p3;
    printf("%zd\n",sizeof(p1));//zd是
    printf("%zd\n",sizeof(p2));
    printf("%zd\n",sizeof(p3));
    return 0;
}//在x86(32位机器)结果都是4,而64位机器都是8

注意:不要被*前面的类型影响对指针大小的判断

注意:编译器如果报警告就可以将%d改成%zd

10、结构体

(1)结构体是为了描述更多的复杂对象而诞生的,有些对象仅仅靠单个的char、int、float…来描述是不够的,这个时候就需要结构体的存在了。
(2)struct是创建结构体的重要关键字,结构的存在使得描述一个对象时,可以用多个数据描述。
(3)结构体成员可以利用“.”或者“->”来访问,两者用法是有区别的

struct Student
{
    char name[20];//名字
    int age;//年龄
    char id[15];//学号
    float score;//成绩
};
int main()
{
    struct Student s1={"张三",20,"2022010823",88.5f};
    struct Student s2={“翠花”,18,"2022030405",98.0f};
    printf("%s %d %s %f",s1.name,s1.age,s1.id,s1.score);

    struct Student *ps1=&s1;
    printf("%s %d %s",(*ps1).name,(*ps1).age,(*ps1).id,(*ps1).score);
   
    printf("%s %d %s %f",ps1->name,ps1->age,ps1->id,ps1->score);
}

11、运算符的优先级和结合性

这个以后找时间补充

12、关键字auto(用的比较少)

(1)意思为“自动”,一般用在局部变量上,表示一个“自动变量”。
(2)代码演示和解说

int main()
{
    int a=10;//局部变量又叫自动变量,自动创建自动销毁,由于所有的局部变量都是自动变量,所以前面的auto被省略了,实际上通常是不会写的。
    return 0;
}

13、移动VS功能模块的小技巧

可以拖动功能模块,更好满足我们的工作需求。
例如下面:有两个源文件,通过拖动这个其中一个源文件可以同时浏览两个源文件。
在这里插入图片描述

14、编译器的自动修正的

有的编译器尽管能运行一些代码,但并不代表该代码就是没有错误的,这是新手常会误会的错误,认为只要有好的编译器,代码能运行就说明正确。但是实际上在写代码的时候我们要尽可能足够严谨,否则就会出现意想不到的错误(编译器也没办法修正了)

15、打开win计算器的方法

win(就是键盘上微软的图标按钮)+R,输入calc就可以弹出计算器。

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

limou3434

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值