3.C语言基本结构

简单的程序结构

下面是一个简单的程序,身高是给出的,体重是在程序中得到的,我们输出的是体重与身高/体重的值。

这里我们更注重的是程序的结构而非程序本身。

示例

1. 类型

每一个变量都有类型(type)。类型用来描述变量的数据的种类,也称数据类型。

数值型变量的类型决定了变量所能存储的最大值与最小值,以及是否允许小数点后出现数字。

示例中只有一种数据类型:int

int(integer):即整型,表示整数。

数据类型还有很多,目前除了 int 以外,我们只再使用另一种:

float(floating-point): 浮点型,可以表示小数

注意:虽然 float 型可以带小数,但是进行算术运算时,float 型要比 int 型慢,而且 float 通常只是一个值的近似值。(比如在一个float 型变量中存储 0.1, 但其实可能这个变量的值为 0.09999987,这是舍入造成的误差)

题外话:我当时学的时候,就没有人告诉我这些知识,你们如果现在是初学,我都感觉到羡慕,你们要少走多少弯路啊!

2. 关键字

int 与float 都是C语言的关键字(keyword),关键字是语言定义的单词,不能用做其他用途。比如不能用作命名函数名与变量名。

关键字:斜体代表C99新增关键字

auto

enum

unsigned

break

extern

return

void

case

float

short

volatile

char

for

signed

while

const

goto

sizeof

continue

if

static

default

struct

do

int

switch

double

long

typedef

else

register

union

restrict

inline

_Bool

_Complex

_Imaginary

如果关键字使用不当(关键字作为变量名),编译器会将其视为语法错误。

保留标识符(reserved identifier):下划线开头的标识符和标准库函数名(如:printf())

C语言已经指定了这些标识符的用途或保留了它们的使用权,如果你使用它们作为变量名,即使没有语法错误,也不能随便使用。

3. 声明

声明(declaration):在使用变量(variable)之前,必须对其进行声明(为编译器所作的描述)。

声明的方式为:数据类型 + 变量名(程序员自己决定变量名,命名规则后面会讲)

示例中的 int weight完成了两件事情。第一,函数中有个变量名为 weight。第二,int 表明这个变量是整型。

编译器用这些信息为变量 weight 在内存中分配空间。

C99 前,如果有声明,声明一定要在语句之前。(就像示例那样,函数体中第一块是声明,第二块才是语句。)

C99 和 C11 遵循 C++ 的惯例,可以把声明放在任何位置。即可以使用时再声明变量。以后C程序中这种做法可能会很流行。但是目前不建议这样。

就书写格式而言,我建议将声明全部放在函数体头部,声明与语句之间空出一行。

4. 命名

weight,height 都是标识符,也就是一个变量,函数或其他实体的名称。因此,声明将特定标识符与计算机内存的特定位置联系起来,同时也就确定了存储在某位置的信息类型或数据类型。

给变量命名时要使用有意义的变量名或标识符。如果变量名无法清楚的表达自身的用途,可以在注释中进一步说明,这是一种良好的编程习惯与编程技巧。

C99 与 C11 允许使用更长的标识符,但是编译器只识别前 63个字符。对于外部标识符,只允许 31 个字符。事实上,你可以使用更长的字符,但是编译器可能忽略超出的部分。(比如有两个标识符都是 64 个字符,但只有最后一个字符不同。编译器可能会视其为同一个名字,也可能不会。标准并未定义在这种情况下会发生什么。)

命名规则:可以用小写字母,大写字母,数字和下划线(_)来命名。名称的第一个字符必须是字符或下划线,不能是数字

操作系统和C库经常使用一个下划线或两个下划线开始的标识符(如:_kcab),因此最好避免在自己的程序中使用这种名称。(避免与操作系统和c库的标识符重复)

C语言的名称区分大小写。即:star,Star,STAR 是不同的。

声明变量的理由:

1.  把所有变量放在一处,方便读者查找和理解程序的用途。

2.  声明变量可以促使你在编写程序之前做好计划(比如你的程序要用什么变量,你可以提前规划)。

3.  声明变量有助于发现程序中的小错误,如拼写错误。

4.  不提前声明变量,C程序编译将无法通过

5. 赋值

赋值(assignment):变量通过赋值的方式获得值。

示例中,weight = 160;是一个 赋值表达式语句。意思是“把值 160 赋给 变量 weight”。

在执行 int weight;时,编译器在计算机内存中为变量 weight 预留的空间,然后在执行这行代码时,把值存储在之前预留的位置。可以给 weight 赋不同的值,这就是 weight 之所以被称为变量的原因。

注意:

● 该行表达式将值从右侧赋到左侧。

● 该语句以分号结尾。

● = 在计算机中不是相等的意思,而是赋值。我们在读 weight = 160;时,我们应该这么读:“将 160 赋给 weight”

● ==表示相等

6. printf() 函数

printf(“我的体重是:%d斤\n,身高与体重的比为:%d”, weight, height / weight);
这是我们示例中的 printf 函数,我们来看两个不那么复杂的:
main(void);
printf("Hi");

首先,printf() 的 圆括号是不是很像 main() ?这表示 printf 是一个函数名,它也是一个函数。圆括号内的内容是从 main() 函数传递给 printf() 函数的信息。该信息被称为参数,更确切的说,是实际参数(actual argument),简称实参。

既然是函数,它其实也是像我们看到的 main函数一样,也有函数头和函数体。

printf() 函数是一个库函数,库函数我们上一节讲函数种类时说过,这是一种不需要程序员去写的,只需要引用头文件 stdio.h就可以直接使用的。但是我们应该知道这一点,详细情况我们后面会说讲。

当程序运行到 printf() 函数这一行时,控制权被转给了printf()函数。函数执行结束后,控制权被返回至主调函数(calling function),该例中是 main() 。

printf() 函数的作用是向我们的显示器输出内容。

此例中,printf() 函数的括号内 分为两部分,一部分在双引号内,另一部分在双引号外,它们中间以逗号隔开。双引号外有两个参数 weight 和 height / weight ,他们分别是变量和表达式(含有常量,变量和运算符的式子),也是指定要被打印的参数(打印到你的屏幕上)。

我们发现,最终我们屏幕上看到的是引号内的内容。我们可以来看一下输出的内容:

我的体重是:160斤

身高与体重的比为:1我们发现:首先引号内的 %d 和\n并没有被输出,%d的位置被替换成了一个整数。为什么会这样呢?

\n代表一个换行符(newline character)。对于 printf 函数来说,它的意思是:“在下一行的最左边开始新的一行”。

也就是说换行符和在键盘上按下 Enter按键相同。既然如此,为何不在键入 printf() 参数时直接使用 Enter键呢?因为编辑器可能认为这是直接的命令,而不是存储在源代码中的指令。换句话说,如果直接按下 Enter键,编辑器会退出当前行并开始新的一行。但是,换行符会影响程序输出的(显示)格式。

换行符是一个转义序列(escape sequence)。转义序列用于难以表示或无法输入的字符。如,\t代表 Tab键,即制表符。\b代表 Backspace键,即退格键。我们在后面会继续讨论。

这样就解释了为何一行的printf() 函数会输出两行。

以下这部分不能理解可以只看结论,能理解更好。

在解释 %d 之前我们先来看一下,weight 和 height / weight 所代表的值。

weight 是被赋值为 160 的,所以 weight 的值就是 160

C语言中,/表示除法, * 表示乘法。

那么 height / weight 的值是多少呢?我们现在不知道这个表达式的值是多少,但是我们知道这个它肯定代表 180 / 160

而最终输出的值是 1 ,这和我们想的不一样,我们知道结果应该是个小数,那么这是为什么呢?

我想可能的原因有两个:

1.  %d 将小数转换为整数

2.  180 / 160 本身在C语言中的值就是整数

我们来测试一下:

int main(void) {
 
    int a = 3;
    int b = 2;
    float c = 1.1f;//f 表示1.1是浮点数
 
    printf("%d\n", c);//%d 用来输出整型
    printf("%f\n", a / b);//%f 用来输出浮点型
    
    return 0;
}

输出:

-1717986918
0.000000


输出并不是我们想要的内容,我们来看一下编译器的警告:

编译器警告:

“printf”: 格式字符串“%d”需要类型“int”的参数,但可变参数 1 拥有了类型“double”

“printf”: 格式字符串“%f”需要类型“double”的参数,但可变参数 1 拥有了类型“int”可以不去理解报错的内容。输出与报错至少说明了一点:

%d 在我的编译器上无法输出浮点型;整型 / 整型 不是浮点型。

那就说明了原因2是对的,即:180 / 160 的值就是 1

为什么 180 / 160 == 1(180 / 160 的值是 1)呢?

因为 weight 和 height 都整数,它们相除结果取整数(向下取整)。

如何输出 float 类型的浮点数?

printf("%f", 2.0f);%d是一个占位符,其作用是指明 num 值的位置。d 代表 以十进制的格式。

还有一点要注意的是,在示例中,第二个输出的整数的参数(height / weight )是一个表达式,我们也可以在程序中添加一个新的变量,然后用这个变量代替上面的表达式作为 printf() 的参数。如:

int main(void)
{
    int height = 180;
    int weight, scale;//scale:比例
    weight = 160;
     scale = height / weight;
    printf(“我的体重是:%d斤\n,身高与体重的比为:%d”, weight, scale);
    return 0;
}

合理的使用表达式作为函数的参数可以简化程序。

也说明在任何需要数值的地方,都可以使用具有相同类型的表达式。

7. 初始化

当程序开始执行时,某些变量会被自动设置为0,而大多数不会。没有默认值并且尚未在程序中被赋值的变量时未初始化的(uninitialized)。

如果试图访问未初始化的变量,可能会得到不可预知的值。在某些编译器中,可能会发生更坏的情况(甚至程序崩溃)。

我们可以用赋值的办法给变量赋初值,但还有更简洁的做法:在变量声明中加入初始值。

例如示例中的 int height = 180数值 180 就是一个初始化式(initializer)。

同一个声明中可以对任意数量的变量进行初始化。如:

int a = 10, b = 15, c = 20;上述每个变量都拥有属于自己的初始化式。接下来的例子,只有 c 有初始化式,a,b没有。

int a, b, c = 20;

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

shangjg3

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

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

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

打赏作者

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

抵扣说明:

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

余额充值