计算机和c语言基础知识

计算机常识

  • 什么是计算机?

  • 顾名思义,就是能够进行数据运算的机器(台式电脑、笔记本电脑、平板电脑、智能手机)

  • 计算机_百度百科

  • 计算机的发明者是谁 ?

  • 关于电子计算机的发明者是谁这一问题,有好几种答案:

  • 1936年英国数学家图灵首先提出了一种以程序和输入数据相互作用产生输出的计算机构想,后人将这种机器命名为通用图灵计算机

  • 1938年克兰德·楚泽发明了首台采用继电器进行工作的计算机,这台计算机命名为Z1,但是继电器是机械式的,并不是完全的电子器材

  • 1942年阿坦那索夫和贝利发明了首台采用真空管*的计算机,这台计算机命名为ABC

  • 1946年ENIAC诞生,它拥有了今天计算机的主要结构和功能,是通用计算机

现在世界上公认的第一台现代电子计算机是1946年在美国宾夕法尼亚大学诞生的ENIAC(Electronic Numerical Integrator And Calculator)

  • 计算机特点是什么?

  • 计算机是一种电器, 所以计算机只能识别两种状态, 一种是通电一种是断电

  • 正是因为如此, 最初ENIAC的程序是由很多开关和连接电线来完成的。但是这样导致改动一次程序要花很长时间(需要人工重新设置很多开关的状态和连接线)

  • 为了提高效率,工程师们想能不能把程序和数据都放在存储器中, 数学家冯·诺依曼将这个思想以数学语言系统阐述,提出了存储程序计算机模型(这是所谓的冯·诺依曼机)

  • 那利用数学语言如何表示计算机能够识别的通电和断电两种状态呢?

    • 非常简单用0和1表示即可
    • 所以计算机能识别的所有指令都是由0和1组成的
    • 所以计算机中存储和操作的数据也都是由0和1组成的

0和1更准确的是应该是高电平和低电平, 但是这个不用了解, 只需要知道计算机只能识别0和1以及存储的数据都是由0和1组成的即可。

什么是计算机语言 ?

  • 在日常生活、工作中, 语言是人们交流的工具

    • 中国人和中国人交流,使用中文语言
    • 美国人和美国人交流,使用英文语言
    • 人想要和计算机交流,使用计算机语言
  • 可以看出在日常生活、工作中,人们使用的语言种类很多
    • 如果一个很牛人可能同时掌握了中文语言和英文语言, 那么想要和这个人交流既可以使用中文语言,也可以使用英文语言
    • 计算机其实就是一个很牛的人, 计算机同时掌握了几十门甚至上百门语言, 所以我们只要使用任何一种计算机已经掌握的语言就可以和计算机交流

如何学好C语言

学习本套开源项目之前 学习本套开源项目中 学习本套开源项目之后
  • 如何达到这样的效果

  • 请往下看

  • 如何达到这样的效果,跟着南哥干就好了

常见的计算机语言类型有哪些?

  • 机器语言

    • 所有的代码里面只有0和1, 0表示不加电,1表示加电(纸带存储时 1有孔,0没孔)
    • 优点:直接对硬件产生作用,程序的执行效率非常非常高
    • 缺点:指令又多又难记、可读性差、无可移植性
  • 汇编语言
    • 符号化的机器语言,用一个符号(英文单词、数字)来代表一条机器指令
    • 优点:直接对硬件产生作用,程序的执行效率非常高、可读性稍好
    • 缺点:符号非常多和难记、无可移植性
  • 高级语言
    • 非常接近自然语言的高级语言,语法和结构类似于普通英文
    • 优点:简单、易用、易于理解、远离对硬件的直接操作、有可移植性
    • 缺点:有些高级语言写出的程序执行效率并不
  • 对比(利用3种类型语言编写1+1)
    • 机器语言

      • 10111000 00000001 00000000 00000101 00000001 00000000
    • 汇编语言
      • MOV AX, 1 ADD AX, 1
    • 高级语言
      • 1 + 1

什么是 C 语言?

  • C语言是一种用于和计算机交流的高级语言, 它既具有高级语言的特点,又具有汇编语言的特点

    • 非常接近自然语言
    • 程序的执行效率非常高
  • C语言是所有编程语言中的经典,很多高级语言都是从C语言中衍生出来的,
    • 例如:C++、C#、Object-C、Java、Go等等
  • C语言是所有编程语言中的经典,很多著名的系统软件也是C语言编写的
    • 几乎所有的操作系统都是用C语言编写的
    • 几乎所有的计算机底层软件都是用C语言编写的
    • 几乎所有的编辑器都是C语言编写的

C语言历史

  • 最早的高级语言:FORTRAN–>ALGOL–>CPL–>BCPL–>C–>C++等

“初,世间无语言,仅电路与连线。及大牛出,天地开,始有 FORTRAN、 LISP、ALGOL 随之, 乃有万种语”

  • 1963年英国剑桥大学推出了CPL(Combined Programming Langurage)语言。 CPL语言在ALGOL 60的基础上接近硬件一些,但规模比较大,难以实现
  • 1967年英国剑桥大学的 Matin Richards(理查兹)对CPL语言做了简化,推出了 BCPL (Base Combined Programming Langurage)语言
  • 1970年美国贝尔实验室的 Ken Thompson(肯·汤普逊) 以 BCPL 语言为基础,又作了进一步的简化,设计出了很简单的而且很接近硬件的 B 语言(取BCPL的第一个字母),并用B语言写出了第一个 UNIX 操作系统。但B语言过于简单,功能有限
  • 1972年至1973年间,贝尔实验室的 Dennis.Ritchie(丹尼斯·里奇) 在 B语言的基础上设计出了C语言(取BCPL的第二个字母)。C语言即保持 BCPL 语言和B语言的优点(精练、接近硬件),又克服了他们的缺点(过于简单,数据无类型等)

C语言标准

  • 1983年美国国家标准局(American National Standards Institute,简称ANSI)成立了一个委员会,开始制定C语言标准的工作
  • 1989年C语言标准被批准,这个版本的C语言标准通常被称为ANSI C(C89)
  • 1999年,国际标准化组织ISO又对C语言标准进行修订,在基本保留原C语言特征的基础上,针对应该的需要,增加了一些功能,命名为C99
  • 2011年12月,ANSI采纳了ISO/IEC 9899:2011标准。这个标准通常即C11,它是C程序语言的现行标准

C语言现状

  • 年度编程语言
  • 该奖项颁发给了一年中最热门的编程语言

为什么要学习C语言?

  • 40多年经久不衰
  • 了解操作系统、编译原理、数据结构与算法等知识的最佳语言
  • 了解其它语言底层实现原理必备语言
  • 基础语法与其它高级语言类似,学会C语言之后再学习其它语言事半功倍,且知根知底

当你想了解底层原理时,你才会发现后悔当初没有学习C语言
当你想学习一门新的语言时, 你才会发现后悔当初没有学习C语言
当你使用一些高级框架、甚至系统框架时发现提供的 API 都是C语言编写的, 你才发现后悔当初没有学习 C 语言
学好数理化,走遍天下都不拍
学好C语言,再多语言都不怕

如何创建C语言程序

  • 这个世界上, 几乎所有程序员入门的第一段代码都是Hello World.
  • 原因是当年C语言的作者Dennis Ritchie(丹尼斯 里奇)在他的名著中第一次引入, 传为后世经典, 其它语言亦争相效仿, 以示敬意

如何创建C语言文件





最后,如果大家想要实时关注我们更新的文章以及分享的干货的话,可以扫描下方二维码关注我们的微信公众号“代码情缘”。

C语言程序组成

  • 手机有很多功能, “开机”,“关机”,“打电话”,“发短信”,"拍照"等等

  • 手机中的每一个功能就相当于C语言程序中的一个程序段(函数)

  • 众多功能中总有一个会被先执行,不可能多个功能一起执行

  • 想使用手机必须先执行手机的开机功能

  • 所以C语言程序也一样,由众多功能、众多程序段组成, 众多C语言程序段中总有一个会被先执行, 这个先执行的程序段我们称之为"主函数"

  • 一个C语言程序由多个"函数"构成,每个函数有自己的功能

  • 一个程序有且只有一个主函数

  • 如果一个程序没有主函数,则这个程序不具备运行能力

  • 程序运行时系统会自动调用主函数,而其它函数需要开发者手动调用

  • 主函数有固定书写的格式和范写


main函数注意点及其它写法

  • C语言中,每条完整的语句后面都必须以分号结尾
int main(){printf("hello world\n") // 如果没有分号编译时会报错return 0;
}
int main(){// 如果没有分号,多条语句合并到一行时, 系统不知道从什么地方到什么地方是一条完整语句printf("hello world\n") return 0;
}
  • C语言中除了注释和双引号引起来的地方以外都不能出现中文
int main(){printf("hello world\n"); // 这里的分号如果是中文的分号就会报错return 0;
}
  • 一个C语言程序只能有一个main函数
int main(){return 0;
}
int main(){ // 编译时会报错, 重复定义return 0;
}
  • 一个C语言程序不能没有main函数
int call(){ // 编译时报错, 因为只有call函数, 没有main函数return 0;
}
int mian(){ // 编译时报错, 因为main函数的名称写错了,还是相当于没有main函数return 0;
}
  • main函数前面的int可以不写或者换成void
#include <stdio.h>
main(){ // 不会报错printf("hello world\n");return 0;
}
#include <stdio.h>
void main(){  // 不会报错printf("hello world\n");return 0;
}
  • main函数中的return 0可以不写
int main(){ // 不会报错printf("hello world\n");
}
  • 多种写法不报错的原因

    • C语言最早的时候只是一种规范和标准(例如C89, C11等)
    • 标准的推行需要各大厂商的支持和实施
    • 而在支持的实施的时候由于各大厂商利益、理解等问题,导致了实施的标准不同,发生了变化
      • Turbo C
      • Visual C(VC)
      • GNU C(GCC)
    • 所以大家才会看到不同的书上书写的格式有所不同, 有的返回int,有的返回void,有的甚至没有返回值
    • 所以大家只需要记住最标准的写法即可, no zuo no die
#include <stdio.h>
int main(){printf("hello world\n");return 0;
}

Tips:
语法错误:编译器会直接报错
逻辑错误:没有语法错误,只不过运行结果不正确

最后,如果你有任何问题,欢迎加我微信 leader_fengy 拉你进学习交流群。

C语言程序练习

  • 编写一个C语言程序,用至少2种方式在屏幕上输出以下内容
   *** *************************
  • 普通青年实现
printf(" *** *** \n");
printf("*********\n");
printf(" *******\n");
printf("  ****\n");
printf("   **\n");
  • 2B青年实现
printf(" *** *** \n*********\n *******\n  ****\n   **\n");
  • 文艺青年实现(装逼的, 先不用理解)
int  i = 0;
while (1) {if (i % 2 == 0) {printf(" *** *** \n");printf("*********\n");printf(" *******\n");printf("  ****\n");printf("   **\n");}else{printf("\n");printf("   ** ** \n");printf("  *******\n");printf("   *****\n");printf("    **\n");}sleep(1);i++;system("cls");
}

最后,如果你有任何问题,欢迎加我微信 leader_fengy 拉你进学习交流群

初学者如何避免程序出现BUG

                          _ooOoo_o8888888o88" . "88(| -_- |)O\ = /O____/`---'\____.   ' \\| |// `./ \\||| : |||// \/ _||||| -:- |||||- \| | \\\ - /// | || \_| ''\---/'' | |\ .-\__ `-` ___/-. /___`. .' /--.--\ `. . __."" '< `.___\_<|>_/___.' >'"".| | : `- \`.;`\ _ /`;.`/ - ` : | |\ \ `-. \_ __\ /__ _/ .-` / /======`-.____`-.___\_____/___.-`____.-'======`=---='.............................................佛祖保佑                   有无BUG
━━━━━━神兽出没━━━━━━┏┓    ┏┓┏┛┻━━━━━━┛┻┓┃        ┃┃   ━    ┃┃ ┳┛   ┗┳ ┃┃        ┃┃   ┻    ┃┃          ┃┗━┓    ┏━┛Code is far away from bug with the animal protecting┃    ┃    神兽保佑,代码无bug┃    ┃┃    ┗━━━┓┃        ┣┓┃     ┏━━┛┛┗┓┓┏━┳┓┏┛┃┫┫ ┃┫┫┗┻┛ ┗┻┛━━━━━━感觉萌萌哒━━━━━━
        ´´´´´´´´██´´´´´´´´´´´´´´████´´´´´´´´´´´████████´´´´´´`´███▒▒▒▒███´´´´´´´´███▒●▒▒●▒██´´´´´´███▒▒▒▒▒▒██´´´´´´´´███▒▒▒▒██´                      项目:第一个C语言程序´´██████▒▒███´´´´´                 语言: C语言´██████▒▒▒▒███´´                   编辑器: Qt Creator ██████▒▒▒▒▒▒███´´´´                版本控制:git-github´´▓▓▓▓▓▓▓▓▓▓▓▓▓▒´´                 代码风格:江哥style´´▒▒▒▒▓▓▓▓▓▓▓▓▓▒´´´´´              ´.▒▒▒´´▓▓▓▓▓▓▓▓▒´´´´´              ´.▒▒´´´´▓▓▓▓▓▓▓▒                   ..▒▒.´´´´▓▓▓▓▓▓▓▒                   ´▒▒▒▒▒▒▒▒▒▒▒▒                      ´´´´´´´´´███████´´´´´              ´´´´´´´´████████´´´´´´´´´´´´´´█████████´´´´´´´´´´´´██████████´´´´             大部分人都在关注你飞的高不高,却没人在乎你飞的累不累,这就是现实!´´´´´´██████████´´´                     我从不相信梦想,我,只,相,信,自,己!´´´´´´´█████████´´´´´´´´´█████████´´´´´´´´´´´████████´´´´´________▒▒▒▒▒_________▒▒▒▒_________▒▒▒▒________▒▒_▒▒_______▒▒__▒▒_____ ▒▒___▒▒_____▒▒___▒▒____▒▒____▒▒___▒▒_____▒▒███____ ▒▒████____████ _███_ _█_███
——————————————————————————女神保佑,代码无bug——————————————————————

注意:编程是一门做中学的学科,BUG 需要亲自动手解决。

最后,如果你有任何问题,欢迎加我 微信 leader_fengy 拉你进学习群交流。

什么是计算机程序?

  • 计算机程序是为了告诉计算机"做某件事或解决某个问题"而用"计算机语言编写的命令集合(语句)

  • 只要让计算机执行这个程序,计算机就会自动地、有条不紊地进行工作,计算机的一切操作都是由程序控制的,离开程序,计算机将一事无成

  • 现实生活中你如何告诉别人如何做某件事或者解决某个问题?

    • 通过人能听懂的语言: 张三你去楼下帮我买一包烟, 然后顺便到快递箱把我的快递也带上来
    • 其实我们通过人能听懂的语言告诉别人做某件事就是在发送一条条的指令
    • 计算机中也一样, 我们可以通过计算机语言告诉计算机我们想做什么, 每做一件事情就是一条指令, 一条或多条指令的集合我们就称之为一个计算机程序

多语言对比

  • C语言
#include<stdio.h>
int main() {printf("南哥带你装B带你飞");return 0;
}
  • C++语言
#include<iostream>
using namespace std;
int main() {cout << "南哥带你装B带你飞" << endl;return 0;
}
  • OC语言
#import <Foundation/Foundation.h>
int main() {NSLog(@"南哥带你装B带你飞");return 0;
}
  • Java语言
class Test
{public static viod main(){system.out.println("南哥带你装B带你飞");}
}
  • Go语言
package main
import  "fmt" //引入fmt库
func main() {fmt.Println("南哥带你装B带你飞")
}

Qt Creator编译过程做了什么?

  • 当我们按下运行按钮的时, 其实Qt Creator编译器做了5件事情
  • 对源文件进行预处理, 生成预处理文件
  • 对预处理文件进行编译, 生成汇编文件
  • 对汇编文件进行编译, 生成二进制文件
  • 对二进制文件进行链接, 生成可执行文件
  • 运行可执行文件

  • Qt Creator编译过程验证
  • 1.编写代码, 保存源文件:

    #include <stdio.h>
    int main(){printf("hello lnj\n");return 0;
    }
    
  • 2.执行预处理编译

  • 执行预处理编译后生成的文件

  • 打开预处理编译后生成的文件

  • 处理源文件中预处理相关的指令
  • 处理源文件中多余注释等

  • 3.执行汇编编译
  • 执行汇编编译后生成的文件
  • 打开汇编编译后生成的文件

  • 4.执行二进制编译
  • 执行二进制编译后生成的文件
  • 打开二进制编译后生成的文件

  • 5.执行链接操作
  • 将依赖的一些C语言函数库和我们编译好的二进制合并为一个文件
  • 执行链接操作后生成的文件

  • 6.运行链接后生成的文件

计算机运算过程分析

  • 1.编写一个简单的加法运算
  • 2.调试编写好的代码, 查看对应的汇编文件


  • 结论:
  • 1.通过地址线找到对应地址的存储单元
  • 2.通过控制线发送内存读取指令
  • 3.通过数据线将内存中的值传输到CPU寄存器中
  • 4.在CPU中完成计算操作
  • 5.通过地址线找到对应地址的存储单元
  • 6.通过控制线发送内存写入指令
  • 7.通过数据线将计算结果传输到内存中

定义和声明

  • 当一个变量被定义的时候,编译器为变量申请内存内容并填充一些值
  • 当一个变量被声明的时候,编译器就知道改变了被定义在其他地方
  • 声明是通知编译器该变量名及相关的类型已存在,不需要在为此申请内存空间

预处理指令的概念

  • C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译
  • 为了区分预处理指令和一般的C语句,所有预处理指令都以符号“#”开头,并且结尾不用分号
  • 预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾。习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件
  • C语言提供了多种预处理功能,如宏定义、文件包含、条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。

宏定义

  • 被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。
  • 宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。在C语言中,“宏”分为有参数和无参数两种。
    ##不带参数的宏定义
  • 格式:#define 标识符 字符串
  • 其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。
#include <stdio.h>// 源程序中所有的宏名PI在编译预处理的时候都会被3.14所代替#define PI 3.14// 根据圆的半径计radius算周长float girth(float radius) {return 2 * PI *radius;
}int main (){float g = girth(2);printf("周长为:%f", g);return 0;
}
  • 注意点:

    1. 宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误
  • 2对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作
#define R 10int main (){char *s = "Radio"; // 在第1行定义了一个叫R的宏,但是第4行中"Radio"里面的'R'并不会被替换成10return 0;}
  • 3)在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查
#define I 100
int main ()
{int i[3] = I;return 0;
}
    1. 宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令
#define PI 3.14
int main (){printf("%f", PI);return 0;
}
#undef PI
void test()
{printf("%f", PI); // 不能使用
}
    1. 定义一个宏时可以引用已经定义的宏名
#define R  3.0
#define PI 3.14
#define L  2*PI*R
#define S  PI*R*R
    1. 可用宏定义表示数据类型,使书写方便
#define String char *
int main(int argc, const char * argv[])
{String str = "This is a string!";return 0;
}

带参数的宏定义

  • C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参
  • 格式: #define 宏名(形参表) 字符串
// 第1行中定义了一个带有2个参数的宏average,#define average(a, b) (a+b)/2int main (){// 第4行其实会被替换成:int a = (10 + 4)/2;,int a = average(10, 4);// 输出结果为:7是不是感觉这个宏有点像函数呢?printf("平均值:%d", a);return 0;}
  • 注意点:
  • 1)宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串.
#define average (a, b) (a+b)/2int main ()
{int a = average(10, 4);return 0;
}
注意第1行的宏定义,宏名average跟(a, b)之间是有空格的,于是,第5行就变成了这样:
int a = (a, b) (a+b)/2(10, 4);
这个肯定是编译不通过的
  • 2)带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,一般用一个小括号括住字符串的参数。
#include <stdio.h>
// 下面定义一个宏D(a),作用是返回a的2倍数值:
#define D(a) 2*a
// 如果定义宏的时候不用小括号括住参数int main ()
{// 将被替换成int b = 2*3+4;,输出结果10,如果定义宏的时候用小括号括住参数,把上面的第3行改成:#define D(a) 2*(a),注意右边的a是有括号的,第7行将被替换成int b = 2*(3+4);,输出结果14int b = D(3+4);printf("%d", b);return 0;
}
  • 3)计算结果最好也用括号括起来
#include <stdio.h>
// 下面定义一个宏P(a),作用是返回a的平方
#define Pow(a) (a) * (a) // 如果不用小括号括住计算结果int main(int argc, const char * argv[])
{// 代码被替换为:int b = (10) * (10) / (2) * (2);// 简化之后:int b = 10 * (10 / 2) * 2;,最后变量b为:100int b = Pow(10) / Pow(2);printf("%d", b);return 0;
}
#include <stdio.h>
// 计算结果用括号括起来
#define Pow(a) ( (a) * (a) )int main(int argc, const char * argv[])      {// 代码被替换为:int b = ( (10) * (10) ) / ( (2) * (2) );
// 简化之后:int b = (10 * 10) / (2 *2);,最后输出结果:25int b = Pow(10) / Pow(2);printf("%d", b);return 0;
}

条件编译

  • 在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才能被执行),这就是条件编译。
  • 为什么要使用条件编译
    • 1)按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。有利于程序的移植和调试。
    • 2)条件编译当然也可以用条件语句来实现。 但是用条件语句将会对整个源程序进行编译,生成 的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目 标程序较短。
      ##if-#else 条件编译指令
  • 第一种格式:
    • 它的功能是,如常量表达式的值为真(非0),则将code1 编译到程序中,否则对code2编译到程序中。
    • 注意:
    • 是将代码编译进可执行程序, 而不是执行代码
    • 条件编译后面的条件表达式中不能识别变量,它里面只能识别常量和宏定义
#if 常量表达式..code1...
#else..code2...
#endif
#define SCORE 67
#if SCORE > 90printf("优秀\n");
#elseprintf("不及格\n");
#endif
  • 第二种格式:
#if 条件1...code1...#elif 条件2...code2...#else...code3...#endif
#define SCORE 67
#if SCORE > 90printf("优秀\n");
#elif SCORE > 60printf("良好\n");
#elseprintf("不及格\n");
#endif

typedef关键字