系列连载

  • 【python / C / C++】

参考

  • 《C语言程序设计(第四版)谭浩强》
  • 【C语言】C语言视频教程
  • 《郝斌 C 语言自学教程》

文章目录

  • C 语言概述
    • A.1 为什么学习 C 语言
    • A.2 怎样学习 C 语言
    • A.3 学习的目标
    • A.4 常见问题答案
    • A.5 课程计划
    • A.6 举例:一元二次方程
  • C 语言编程预备知识
    • B.1 cpu、内存条、硬盘、主板、显卡之间的关系
    • B.2 Hello World 程序如何运行起来的
    • B.3 什么是数据类型
    • B.4 什么是变量
    • B.5 cpu、内存条、vc++6.0、操作系统之间的关系
    • B.6 变量为什么必须初始化
    • B.7 如何定义变量
    • B.8 什么是进制
    • B.9 常量在 C 语言中是如何表示的
    • B.10 常量以什么样的二进制代码存储在计算机里
    • B.11 代码规范化
    • B.12 什么是字节
    • B.13 不同类型数据之间相互赋值的问题
    • B.14 什么是 ASCII
    • B.15 字符的存储本质上与整数的存储方式相同
  • 1 基本概念
    • 1.1 C语言的起源
    • 1.2 C语言中使用的词汇分类
    • 1.3 程序
    • 1.4 算法的特性
    • 1.5 算法的表示方法
  • 2 工具 + 牛刀小试
    • 2.1 hello world
    • 2.2 求 sin
    • 2.3 两个数比较大小
  • 3 数据类型
    • 3.1 常量和符号常量
    • 3.2 变量
    • 3.3 整型
      • 3.3.1 整型常量
      • 3.3.2 整型变量
    • 3.4 浮点型(实型)
      • 3.4.1 浮点型常量的表示方法
      • 3.4.2 实型变量
    • 3.5 字符型数据
      • 3.5.1 字符型常量
      • 3.5.2 字符型变量
    • 3.6 字符串型数据
      • 3.6.1 字符串常量
    • 3.7 各类数据类型之间的混合运算
  • 4 基本的输入输出函数的用法

C 语言概述

A.1 为什么学习 C 语言

1)C 的起源和发展


2)C 的特点

  • 优点
    代码量小、速度快、功能强大
  • 缺点
    危险性高、开发周期长、可移植性不强(相对 java)

3)C 的应用领域(系统软件)

4)C 的重要性

A.2 怎样学习 C 语言

多思考、多上机

A.3 学习的目标

A.4 常见问题答案

1)学习 java 为什么建议先学 C 语言

2)没学过计算机专业课程能够学懂 C 语言?

3)英语和数学不好能学好 C 么?

A.5 课程计划

A.6 举例:一元二次方程

#include<stdio.h>
#include<math.h>int main(void)
{int a = 1;int b = 5;int c = 6;double delta = b*b - 4 * a*c;double x1;double x2;if (delta > 0){x1 = (-b + sqrt(delta)) / (2 * a);x2 = (-b - sqrt(delta)) / (2 * a);printf("方程有两个解,分别为 x1 = %f, x2 = %f\n", x1, x2);}else if (delta == 0){x1 = x2 = -b  / (2 * a);printf("方程有一个解, x1 = x2 = %f\n", x1);}else{printf("方程没有解!\n");}return 0;
}


C 语言编程预备知识

B.1 cpu、内存条、硬盘、主板、显卡之间的关系

比如看电影

电影存在硬盘上

双击电影,copy 调入到内存条中,CPU 对内存条中的电影处理

通过声卡和显卡播放出来

CPU、内存条、硬盘、显卡都在主板上

B.2 Hello World 程序如何运行起来的

compile(编译) -> build (链接) 生成 .exe

buildExecute(操作系统调用 CPU,执行 .exe)

B.3 什么是数据类型

基本类型数据

  • 整数
    整型 – int 4
    短整型 – short int 2
    长整型 – long int 8
  • 浮点数(实数)
    • 单精度浮点数 – float 4
    • 双精度浮点数 – double 8
  • 字符
    char 1

复合类型数据

  • 结构体
  • 枚举
  • 共用体

B.4 什么是变量

本质上是内存中一段存储空间

B.5 cpu、内存条、vc++6.0、操作系统之间的关系

int i = 3;

vc++6.0 请求操作系统在内存条中分配空间,与变量 i 之间产生关联

B.6 变量为什么必须初始化

所谓初始化就是赋值的意思

B.7 如何定义变量

B.8 什么是进制

逢 x 进一


10 进制转成其它进制

#include<stdio.h>int main(void)
{int i = 88;printf("i= %d\n", i); //以 10 进制输出printf("i= %o\n", i); // 以 8 进制输出printf("i= %x\n", i); // 以 16 进制输出return 0;
}

output

i= 88
i= 130
i= 58

16 进制转成其它进制

#include<stdio.h>int main(void)
{int i = 0x11;printf("i= %d\n", i); //以 10 进制输出printf("i= %o\n", i); // 以 8 进制输出printf("i= %x\n", i); // 以 16 进制输出return 0;
}

output

i= 17
i= 21
i= 11

B.9 常量在 C 语言中是如何表示的



“A” 为 ‘A’ 和 ‘\0’

#include<stdio.h>int main(void)
{char ch = 'A';char ch = 'B';return 0;
}

会报错

error C2374: “ch”: 重定义;多次初始化

B.10 常量以什么样的二进制代码存储在计算机里


字符->十进制整数(通过 ASCII)->二进制

B.11 代码规范化

成对,换行,缩进,空格

代码的可读性更强

使程序更不容易出错

B.12 什么是字节

字节就是存储数据的单位,并且是硬件所能访问的最小单位

位可以通过运算符以软件的形式操作

B.13 不同类型数据之间相互赋值的问题

涉及到溢出,暂时不考虑

#include<stdio.h>int main(void)
{int i = 0X7FFFFFFF;int j = 0X7FFFFFFF+1;int k = 0X7FFFFFFF + 2;int l = sizeof(i);printf("%d\n", l);printf("%d %d %d", i,j,k);return 0;
}

output

4
2147483647 -2147483648 -2147483647

B.14 什么是 ASCII

不是一个值,而是一种规定

规定了不同的字符是使用哪个整数去表示

‘A’-65
‘B’-66
‘a’-97
‘b’-98
‘0’-48

GB3312码
UTF-8码

B.15 字符的存储本质上与整数的存储方式相同


1 基本概念

1.1 C语言的起源

C语言是在70 年代初问世的。一九七八年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言。同时由B.W.Kernighan和D.M.Ritchit合著了著名的“THE C PROGRAMMING LANGUAGE”一书。通常简称为《K&R》,也有人称之为《K&R》标准。但是,在《K&R》中并没有定义一个完整的标准C 语言,后来由美国国家标准协会(American National Standards Institute)在此基础上制定了一个C 语言标准,于一九八三年发表。通常称之为ANSI C。

1.2 C语言中使用的词汇分类

在C语言中使用的词汇分为六类:

  • 标识符:在程序中使用的变量名、函数名、标号等统称为标识符。(字母或者下划线开头)
  • 关键字
    • 类型说明符(int double)
    • 语句定义符(if else)
    • 预处理命令字(include)
  • 运算符
  • 分隔符(逗号和空格)
  • 常量
  • 注释符等。

1.3 程序

一个程序应包括:

  • 对数据的描述。在程序中要指定数据的类型和数据的组织形式,即数据结构(data structure)。
  • 对操作的描述。即操作步骤,也就是算法(algorithm)——做任何事情都有一定的步骤。为解决一个问题而采取的方法和步骤,就称为算法。。

数据结构+算法=程序

如何理解数据结构和算法的关系,根据实际问题去设计数据结构,在数据结构的基础上进行算法设计。即,数据结构特点决定了算法的设计。

结构化程序设计方法:

  • 自顶向下;
  • 逐步细化;
  • 模块化设计;
  • 结构化编码。

1.4 算法的特性

  • 有穷性:一个算法应包含有限的操作步骤而不能是无限的。
  • 确定性:算法中每一个步骤应当是确定的,而不能应当是含糊的、模棱两可的。
  • 有零个或多个输入。
  • 有一个或多个输出。
  • 有效性:算法中每一个步骤应当能有效地执行,并得到确定的结果。

对于程序设计人员,必须会设计算法,并根据算法写出程序。

1.5 算法的表示方法

  • 用自然语言表示算法
  • 用流程图表示算法
  • 用 N-S 流程图表示算法(这个没有用过)
  • 用伪代码表示算法(伪代码使用介于自然语言和计算机语言之间的文字和符号来描述算法。)
  • 用计算机语言表示算法(eg:C, C++, python)

下面以流程图表示算法为例

eg:

注意平行四边形是输入输出框,这个我用的比较少!!!

可以用 顺序结构、循环结构、选择结构,三种基本结构共同特点

  • 只有一个入口;
  • 只有一个出口;
  • 结构内的每一部分都有机会被执行到;
  • 结构内不存在“死循环”。

2 工具 + 牛刀小试

【程序安装】Win10环境下vc++6.0绿色版安装

2.1 hello world

#include<stdio.h>
void main()
{printf("hello, world!\n");
}

2.2 求 sin

这里是弧度,联想 s i n ( π / 2 ) = 1 sin(\pi/2) = 1 sin(π/2)=1 即可,弧度向度数转换的公式为乘上 180 / π 180/\pi 180/π

#include<stdio.h>
#include<math.h>
void main()
{double x,s;printf("input number:\n");scanf("%lf",&x);s=sin(x);printf("sine of %lf is %lf\n",x,s);
}

2.3 两个数比较大小

#include<stdio.h>
#include<math.h>
int max(int a, int b);void main()
{int x,y,z;int max(int a, int b);printf("input two numbers:\n");scanf("%d%d",&x,&y);z = max(x,y);printf("maxmum=%d\n",z);
}int max(int a, int b)
{if (a>b)return a;elsereturn b;
}

3 数据类型


图片来源:https://www.bilibili.com/video/av2831981/?p=2

对于基本数据类型,按照其值是否可以改变,可以分为,常量变量

3.1 常量和符号常量

在程序执行过程中,其值不发生改变的量称为常量
符号常量:用标示符代表一个常量。其一般形式为 #define 标识符 常量

#include<stdio.h>
#define Price 30
void main()
{int num, total;num = 10;total = num*Price;printf("total=%d\n",total);
}

预处理命令,在没有编译之前,把所有的 Price 都替换成了 30

使用符号常量的好处是:

  • 含义清楚;
  • 能做到“一改全改”

3.2 变量

int k = 3;

图片来源:https://www.bilibili.com/video/av2831981/?p=2

3.3 整型

3.3.1 整型常量

整型常量的表示方法有如下三种:

  • 八进制:0 开头(零)
  • 十进制
  • 十六进制:0x 或者 0X(零)

3.3.2 整型变量

整型数据在内存中的存放形式:

数值是以补码表示的

  • 正数的补码与原码相同;
  • 负数的补码:将该数的绝对值的二进制形式按照按位取反再加1

下面看一个求 8 位二进制补码的例子!


CPU 是如何识数的?

补码的由来,为啥是 -128~127(±0)

与或非(道生一,一生二,二生三,三生万物)

用一个与门和一个异或门就可以实现二进制加法

你管这破玩意叫 CPU ?


整型变量的分类

  • int
  • short int 或 short
  • long int 或 long
  • unsigned

unsigned 又可以和上面三个组合起来!

占多少字节跟系统和编译器规定有关!可以在编译器上自己试试查看,用 sizeof!!!

#include<stdio.h>
void main()
{printf("short:%d\n",sizeof(short));printf("short int:%d\n",sizeof(short int));printf("int:%d\n",sizeof(int));printf("long:%d\n",sizeof(long));printf("long int:%d\n",sizeof(long int));printf("unsigned:%d\n",sizeof(unsigned));printf("unsigned short:%d\n",sizeof(unsigned short));printf("unsigned int:%d\n",sizeof(unsigned int));
}


int 的范围,4字节32位, − 2 31 -2^{31} −231 ~ 2 31 − 1 2^{31}-1 231−1(为什么减1,因为0),也即 -2147483648 ~ 2147483647,其它的以此类推!

unsigned, 0 0 0 ~ 2 32 − 1 2^{32}-1 232−1,0~4294967295,也即 0x0~0xffff ffff

来个简单的例子

#include<stdio.h>
void main()
{int a,b,c,d;unsigned u;a = 12, b =-24, u = -10;c = a+u;d = b+u;printf("%a+u=%d,b+u=%d\n",c,d);
}


纳尼?unsigned 还可以赋值负数?

  • %d 有符号10进制整数
  • %u 无符号10进制整数

换成 %u 试试,修改 printf("%a+u=%u,b+u=%u\n",c,d);

哈哈,现出了庐山真面目, 2 32 2^{32} 232 -34 = 429496726

试试,b+u = -1 的例子, 2 32 2^{32} 232 -1 = 4294967295


再来个简单的例子看看溢出的问题

#include<stdio.h>
#include<math.h>
void main()
{short int a,b;a = pow(2,8*sizeof(short int)-1)-1;b = a + 1;printf("%d,%d\n",a,b);
}


根据前面的例子我们知道,short int 两个字节,范围为 − 2 15 -2^{15} −215~ 2 15 − 1 2^{15}-1 215−1, 2 15 2^{15} 215为 32768,上面的例子我们让 a 被赋值为最大的数,加一后的 b 竟然成了负数,也就是溢出了,原理如下!最高位符号位,0 表示正数,1表示负数!计算机用补码的形式存储数据,32767+1 算出来的正好是 -32768,用前面所讲的公式计算,取反+1

3.4 浮点型(实型)

3.4.1 浮点型常量的表示方法

  • 十进制数形式
  • 指数形式(阶码标志,e 或者 E,科学计数法)

在计算机中是按照指数形式存储的,浮点型常数不分单、双精度,都按双精度double型处理

3.4.2 实型变量

1)实型数据在内存中的存放形式

  • 小数部分的位数越多,精度越高
  • 指数部分的位数越多,数值范围越大

小数部分有23bit, 2 23 = 8388608 2^{23} = 8388608 223=8388608,float 的有效数字为 6-7 位,超过了就无法精确了!

关于 float 的取值范围参考 IEEE标准中32位、64位浮点数的取值范围
这里仅给出结论

2)实型变量的分类

  • float
  • double
  • long double

字节数分别如下

3)浮点型数据的舍入误差
前面说了有效数字是7位

#include "stdio.h"
void main()
{float a,b;a = 123456.789e5;b = a + 20;printf("%f\n",a);printf("%f\n",b);
}

口算的话,结果为

  • 12345678900
  • 12345678920

可是计算机计算出来的结果如下

float 32 位能保证前6位都是精确的,部分第七位也行,第八位也未必不一样,具体解释如下 关于float型是单精度的有效位数是7位,为什么在下面的例子中这8位都是准确的呢?

#include"stdio.h"
void main(){printf("%f\n",1.0/3*3);printf("%f\n",1/3*3);printf("%f\n",3/2);printf("%f\n", (float)(3/2));printf("%d\n", 3/2);
}

output

1.000000
0.000000
0.000000
1.000000
1

3.5 字符型数据

3.5.1 字符型常量



3.5.2 字符型变量


#include"stdio.h"
void main(){int a = 120;int b = 121;char c = 'z';printf("%c, %c, %c\n",a,b,c);printf("%d, %d, %d\n",a,b,c);
}

output

x, y, z
120, 121, 122

试试把小写字母转化为大写字母,查 ASCII 码表知道,‘A’ 是 65,‘a’ 是 97,相隔 32,我们可以利用这个 32,来实现大小写字母的转换!

#include "stdio.h"
void main()
{char a,b;a = 'a';b = 'b';a = a - 32; //对应着 ASCII 码为 65,是 Ab = b - 32; //对应着 ASCII 码为 66,是 Bprintf("%c %c\n%d %d\n", a, b, a, b);
}

output

A B
65 66

3.6 字符串型数据

3.6.1 字符串常量


3.7 各类数据类型之间的混合运算

  • 自动转换(精度不降低的原则)
  • 强制转换

1)自动转换

注意 float 都是转化为 double 来计算的


2)强制转换

注意第二条,类型转换只是临时的(孙悟空72变,但是还是会变回孙悟空的)!

#include "stdio.h"
void main()
{float PI = 3.1415926;printf("%d, %f\n", int(PI), PI);
}

output

3, 3.141593

4 基本的输入输出函数的用法

1)printf()——将变量的内容输出到显示器上

四种用法

  • printf(“字符串\n”);
  • printf(“输出控制符”,输出参数);
  • printf(“输出控制符1 输出控制符2…”,输出参数1,输出参数2)
    输出控制符和输出参数个数必须一一对应
  • printf(“输出控制符 非输出控制符”, 输出参数)

输出控制符包含如下

%d – int
%ld – long int
%c – char
%f – float
%lf – double
%x(或者%X或者%#X)——%#x 输出 0X16进制 – 16进制输出
%o – 8 进制
%s

#include<stdio.h>int main(void)
{int i = 100;int k = 11;printf("%#x %d\n", i, k);return 0;
}

output

0x64 11

为什么需要输出控制符

  • 01 组成的代码可以表示数据也可以表示指令
  • 如果 01 组成的代码表示的是数据的话,那么同样的 01 代码组合以不同的输出格式输出就会有不同的输出结果
    scanf()

2)scanf()——通过键盘讲数据输入到变量中

两种用法

用法一 scanf(“输入控制符”,输入参数)
功能,将从键盘输入的字符转化为输入控制符所规定的数据,然后存入以输入参数的值为地址的变量中

#include<stdio.h>int main(void)
{int i;scanf("%d", &i); // &i 表示取 i 的地址printf("i = %d\n", i);return 0;
}

output

145
i = 145

用法二 scanf(“非输入控制符 输入控制符”,输入参数)
功能,将从键盘输入的字符转化为输入控制符所规定的数据,然后存入以输入参数的值为地址的变量中
非输入控制符必须原样输入

#include<stdio.h>int main(void)
{int i;scanf("m%d", &i); printf("i = %d\n", i); return 0;
}

测试1

123 // 输入 123,i 的没有被初始化
i = -858993460

测试2

m123
i = 123

测试1

m123n123m
i = 123

如何使用 scanf 编写出高质量代码

1、使用 scanf 之前最好先使用 printf 提示用户以什么样的方式来输入

2、scanf 中尽量不要使用非输入控制符,尤其是不要用 \n

3、应该编写代码对用户的非法输入做适当的处理

一次输入多个

#include<stdio.h>int main(void)
{int i,j,k;printf("请输入三个值,中间用逗号隔开!\n")scanf("%d,%d,%d", &i, &j, &k);printf("i = %d, j = %d, k = %d\n", i, j, k); return 0;
}

out

请输入三个值,中间用逗号隔开:
1,2,3
i = 1, j = 2, k = 3



读到不是整数的时候,之后的变量就会随机初始化


#include<stdio.h>int main(void)
{int i, j;scanf("%d", &i);printf("i = %d\n", i);// ...scanf("%d", &j);printf("j = %d\n", j);return 0;
}

test1

12
i = 12
34
j = 34

test2

123m
i = 123
j = -858993460

读完 123 后读到了 m,给 j 随机初始化了

改进

#include<stdio.h>int main(void)
{int i, j;char ch;scanf("%d", &i);printf("i = %d\n", i);// ...while ((ch = getchar()) != '\n')continue;scanf("%d", &j);printf("j = %d\n", j);return 0;
}

测试

123m
i = 123
4
j = 4

【C】Data type相关推荐

  1. 【Planning】Firm type used in R3 Planning - Manual Firm and regular run

    Purpose: 前文主要记录了SAP-auto firm的配置及应用:而在planning run中,我们还可以使用manual Firm来实现firm: 不同于SAP-firm,manual Fi ...

  2. 【转】data和attr的用法与区别

    attr()的用法 attr()获得属性值 通过attr()获得属性时,可以这样$(selector).attr(attrName).注意,其返回值始终是string型!  eg : 通过attr() ...

  3. 【Elasticsearch】Data too large, data for which is larger than the limit of

    1.概述 参考:elasticsearch报Data too large异常处理 在线上ES集群日志中发现了如下异常,elasticsearch版本为7.3.2 [2021-03-16T21:05:1 ...

  4. 【转】Data truncation: Truncated incorrect DOUBLE value:Mysql Update时

    转自http://blog.csdn.net/iwtbavcp/article/details/6455704 真的是一篇很冷的帖子,解决了我的大问题   Mysql Update  sData tr ...

  5. 【Mybatis-Plus】【异常】Inferred type ‘E‘ for type parameter ‘E‘ is not within its bound;

    问题描述 今天继承Mybatis-Plus里面的BaseMapper做的Dao层接口,实现selectPage()方法,但是一直报异常,代码和报错信息如下: @Service public class ...

  6. 【RS-Attack】Data Poisoning Attacks to Deep Learning Based Recommender Systems NDSS‘21

    Data Poisoning Attacks to Deep Learning Based Recommender Systems NDSS'21 首个在基于深度学习的推荐系统中进行投毒攻击的研究.文 ...

  7. 【Pytorch】data.norm(几种范数(norm)的详细介绍)

    范数(norm) 几种范数的简单介绍&data.norm()使用 1. 范数(norm)的简单介绍 1.1 L-P范数 1.2 L0范数 1.3 L1范数 1.4 L2范数 1.5 ∞-范数 ...

  8. 【bug】data functions should return an object

    很多文章都说这个报错是因为data对象没有return 即下面这样: 但我遇到的报错不是这个原因引起的 除了报data functions should return an object之外,还有很多 ...

  9. 【Antdv】input type=number去掉上下箭头、提示文字、鼠标滚轮

    数字输入框在项目中十分常用,但是有一些属性影响使用体验.解决方案如下: 1.整数文字提示 解决方法,将title="" title="" 2.鼠标滚轮会修改数值 ...

最新文章

  1. 【安装PHP】如何在openSUSE42.1下编译安装PHP7
  2. Chrome 键盘快捷键(Mac)
  3. 【OpenGL从入门到精通(六)】纹理对象与纹理坐标
  4. jwt配置 restful_SpringBoot实现JWT保护前后端分离RESTful API
  5. 为什么年轻人挣得很多还是穷?北上广深挑战指数报告~
  6. cts测试之CertificateTest
  7. 【转】putty基本操作--不错
  8. 武汉理工大学计算机学院夏令营,武汉理工大学计算机科学与技术学院(专业学位)软件工程保研夏令营...
  9. 2020 字节跳动 面经
  10. Three.js - 加载 .OBJ 格式模型(十六)
  11. 知识存储之Apache Jena
  12. 8种常见液相色谱异常峰
  13. TrueLicense实现产品License验证
  14. 狼人杀游戏法官主持软件和会员管理积分系统开发
  15. 玩转娱乐化时代|淘系互动团队几年的技术沉淀+经验都在这!
  16. Apache Apisix 安全漏洞(CVE-2020-13945)
  17. EEG微状态:注意力缺陷多动症ADHD新的功能生物标记物
  18. Face Alignment
  19. Windwos XP 密匙
  20. LabVIEW弹窗实现

热门文章

  1. SQLite数据库管理器:SQLPro for SQLite for Mac
  2. 如何使用计算机视觉进行人脸识别和测试?
  3. 2023最新FPS实时帧率iApp源码+实时显示屏幕帧率
  4. 大学计算机专业绩点在3.5算好,大学平均绩点3.5算差吗 算什么水平
  5. Python:Kendall tau相关系数的计算
  6. SuperMap支持的国产化环境
  7. iOS触摸事件全面解析
  8. 怎么做食品安全教育培训主题班会PPT课件?
  9. JVM 的可达性分析法和四种引用
  10. vivox21android版本9升级,vivo X21是什么系统