初始C语言(上)
一、开门见山
1.1.第一个C语言程序
1.2.程序解剖
二、数据类型
2.1.为什么引入数据类型?
2.2.C语言中有哪些基本数据类型?
2.3.每种类型的大小是多少?
2.4.数据类型的简单使用
三、标识符
3.1.什么是标识符
3.2.标识符的命名
四、变量
4.1.引入-熟悉变量常量概念
4.2.变量的创建
4.3.局部变量与全局变量
4.4.变量的作用域和声明周期
五、常量
5.1.字面常量
5.2.const修饰的常变量
5.3.#define定义的标识符常量
5.4.枚举常量
六、字符串
6.1.什么是字符串?
6.2.实例展示
七、转义字符
7.1.引入
7.2.什么是转义字符?
7.3.常见转义字符表
7.4.小试牛刀
八、注释
8.1.什么是注释?
8.2.注释风格
本章为大家介绍的是初识C语言(上),因为是初识,所以下面要介绍的内容主要涉及简单的概念,以及一些基础的知识点。大家在学习这部分的时候也不要太过于纠结,只需简单理解,后续我还会对下面的知识点详细介绍(大家期待一下吧)。博主尽量做到每一篇文章都浅显易懂,句句重点✍️
在学习具体内容之前,先让我们来看一个经典的C程序例子——Hello World
代码展示:
#include//包含一个叫stdio.h
//std-标准 全称为:standard input output是一个头文件
//main前面的int表示main函数调用返回一个整数值
int main()//主函数-程序的入口有且只有一个
{
//在“{}”大括号之内完成任务
printf("Hello World\n");//在屏幕上输出Hello World
//"\n"表示在屏幕上打印出hello world后会换行
//print function打印函数是库函数:由c语言提供
//因此第一行引用#include表示我们像C语言告知,我们要引用它的库函数
return 0;//返回0
}
在运行上面这段程序时屏幕上会打印出Hello World, 目前我们要做的是从宏观上考察一个C程序的特点,就像你认识一个陌生人时,在对它进行深入了解之前,先看看它的外貌和举止一样。那么C程序究竟有什么特点呢?从上面这个例子我们可以大致归纳出以下几点:
1、C程序的入口:一个标准的C程序必须有且仅有一个用main命名的函数,这个函数称为主函数,并且C程序总是从main()函数开始执行,与他在程序中的位置无关。
2、函数:每个C程序都有一个主函数main。int-表示执行完main()函数后将返回一个整数给操作系统,他与main函数的最后一条语句return 0是呼应的,返回0值给操作系统表示程序正常结束。()内是函数的形参,这里表示形参为空。
函数体:函数体由函数首部下面最外层的一对{}中的内容组成,我们要执行的任务都在{}内部完成。当然现在我们只需要记住这个基本框架就行,后续我还会对函数部分进行详细介绍。
3、C语句:除了复合语句外,C语句都以分号作为结束标志,复合语句,用{}括起来组成的一个语句成为复合语句,在程序中把复合语句看做是单条语句,而不是多条语句
4、头文件:在程序中,我们经常会调用系统提供的库函数,在调用之前我们需要通过编译预处理命令将相应的头文件包含到本文件中。例如上述例子中用到了系统输出函数-printf(),我们需要用下面的编译预处理命令将头文件stdio.h包含到本文件中。—#include
5、注释:上述代码中所出现的//均为注释符,注释就是对程序的功能进行必要的说明和解释,现在我们只需要了解,后面会做详细介绍。
注意:C语言代码中的所有标点均为英文格式下的标点
首先我们要清楚,我们用C语言写程序目的是为了解决生活中形形色色的问题,因此计算机语言必须要有能力描述生活中的问题。比如我们去菜场买菜,遇到了一位60岁的农民伯伯在叫卖1.2元每公斤的白菜。现在我们要描述农民伯伯的年龄以及白菜的价格,于是就引入了整数类型描述年龄;浮点数(小数)类型描述价格。
其实往深了说,对于计算机硬件系统来说,数据类型的概念并不存在,数据之所以要区分类型,主要是为了能更有效地组织数据,规范数据的使用,提高程序的可读性。
应用方面:下面介绍的这些数据类型是为了创建变量而服务的
char | 字符数据类型 |
short | 短整型 |
int | 整形 |
long | 长整型 |
long long | 更长的整形 |
float | 单精度浮点数 |
double | 双精度浮点数 |
注意:C语言中没有字符串类型,字符串通常储存在字符数组中。
这里通过C语言中的一个关键字也是操作符sizeof——计算类型或者变量所占空间的大小。
#include
int main()
{
printf("%d\n", sizeof(char)); //1-单位(byte)字节
printf("%d\n", sizeof(short)); //2
printf("%d\n", sizeof(int)); //4
printf("%d\n", sizeof(long)); //4
printf("%d\n", sizeof(long long)); //8
printf("%d\n", sizeof(float)); //4
printf("%d\n", sizeof(double)); //8
return 0;
}
注意:
1、这里int和long占用空间相同,因为C语言标准规定long的大小不小于int的大小
2、printf()函数其中“”双引号中的内容表示打印格式,这里%d表示打印一个10进制整数,\n表示打印后换行。
1byte | 8bit(1bit=1个二进制位) |
1kb | 1024byte |
1mb | 1024kb |
1gb | 1024mb |
1tb | 1024gb |
1pb | 1024tb |
大致看过了这些类型后,你是否会有这样的疑问:同样都是表示整形,为什么要分成int、long、long long这样三种类型?
例如:现在想表示一个年龄如果用int age=20,那就会太浪费空间了,而short是两个字节(16个二进制位)存储整数的范围是0-2^16-1(65535)用来表示age已然足够,因此用short age=20更为合适。因此呢类型丰富给我们的选择性就会变多,我们对空间的利用率也会变高。
#include
int main()
{
char ch = 'w'; //char表示向内存申请1个字节空间将字符'w'赋值给ch
printf("%c\n", ch);//打印字符变量用%c
int salary = 20000;//int表示向内存申请1个字节空间将整数20000赋值给salary
printf("%d\n",salary);
return 0;
}
1、在计算机编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。标识符可分为系统预定义标识符和用户自定义标识符两类。
2、顾名思义,系统预定义标识符的含义是由系统预先定义好的,例如2.4中的主函数名main、库函数名printf等
3、用户自定义标识符是由用户根据需要自行定义的标识符,通常做函数名。变量名等。例如2.4中提到的ch、salary等。
一般的标识符命名规则如下:
1、由英文字母、数字和下划线组成,且必须以英文字母或下划线开头。
2、不允许使用关键字作为标识符的名字,同时标识符名也不应该与库函数名重名。
3、在C语言中标识符可以是任意长度的。
4、标识符的命名应以直观且易于拼读为宜,即做到“见名知意”,最好使用英文单词及其组合。给变量起一个有意义的名字,有助于程序自我文档化,减少所需注释的数量。
5、标识符区分大小写。例如sum、Sum、SUM是三个不同的标识符,虽然C语言区分大小写标识符,但为避免引起混淆,最好不要使用仅靠大小写区分的相似度标识符。
举个例子
相信大家都听过《乌鸦喝水》的故事吧,聪明的乌鸦为了能够喝到水,将石子衔入瓶内使水位不断升高。那么水是变量还是常量呢?其实我们应该这样说,水的体积在过程中是不会变化,而水的高度在不断变化,所以:水的体积是常量;水位是变量。
其实常量和变量的概念很简单,无非顾名思义:
变量 | 可以改变的量 |
常量 | 不变的量 |
这部分很简单,只需要 类型+变量名=初始值,这里就不在过多赘述
//整形变量
int age = 150;
//浮点变量
float weight = 45.5;
//字符变量
char ch = 'w';
局部变量:指的是作用在代码块{ }内部的变量
全局变量:指作用在代码块{ }外部的变量
注意:当局部变量和全局变量名字相同的时候,局部变量优先 。例如:
#include
int a = 100;
int main()
{
int a = 10;
//当局部变量和全局变量的名字相同的时候,局部变量优先
//局部变脸和全局变量的名字建议不要相同-容易误会,产生bug
printf("%d\n", a);输出10
return 0;
}
但是需要注意的是,局部变量和全局变量的名字建议不要相同,因而这样写容易产生bug,为了大家养成良好的代码风格,希望能够规避这种写法。
局部变量的作用域:变量所在的局部范围
如下图代码会报错,变量a只能作用在它所在的代码块内部
全局变量的作用域:整个工程
如下图:全局变量可以在整个工程中的其他源文件中使用,使用前需要声明(extern)关键字---后面会讲到
局部变量的生命周期:进入作用域生命周期开始,出作用域生命周期结束
全局变量的生命周期:整个程序的生命周期
对于字面常量,我们只需要知道有字面常量这个概念就行,因为这种常量意义不大:
#include
int main()
{ //字面常量
3.14;
'a';
"abcd";
return 0;
}
如下图,执行下图代码会报错,因为const修饰变量使变量具有了常属性,也就是说被count修饰后的变量就不能再直接修改了。
但是需要注意的是:虽然变量具有了常属性,但它本质上依旧是一个变量
这点也好理解,如下代码:
注意:定义后的标识符不可修改,如下面的MAX不可以修改
#include
#define定义的标识符常量
#define MAX 100
int main()
{
printf("%d\n",MAX);
return 0;
}
其实个人认为,枚举常量就目前来说还是较难理解的,我们可以记忆枚举常量的这种形式,后面遇到的话,在根据实例理解。
#include
// 枚举关键字enum
enum Sex
{
MAL,FEMAL,SECRET
};//MAL,FEMAL,SECRET——枚举常量
int main()
{
printf("%d\n", MAL); //0
printf("%d\n", FEMAL); //1
printf("%d\n", SECRET);//2
//默认0 1 2
return 0;//枚举常量不能改,例如不能MAL=3
}
首先我们要清楚这个概念:C语言中的字符串就是由双引号引起的一串字符
特别注意:字符串的结束标志是一个\0的转义字符(转义字符后续介绍)。在计算字符串长度的时候\0是结束标志,不算作字符串内容
C语言中我们用字符数组来存放字符串,如下代码:
(这里为介绍字符串简单引出数组,后续我会有详细介绍哦)
#include
include //strlen()函数的头文件
int main()
{
char arr1[] = "abc";//字符串abc后面隐藏一个\0-结束标志
char arr2[] = {'a','b','c'};//这样写,字符串没有结束标志
//strlen-库函数-用来计算字符串的长度-以\0结束
strlen(arr1)//输出3
strlen(arr2)//输出-随机值,无字符串结束标志
printf("%s\n",arr1); //输出abc
printf("%s\n", arr2);//输出abc烫烫烫烫蘟bc
//因为找不到结束标志,所以乱码
return 0;
}
其实也可以通过调试中的监视窗口看到数组中的内容:
在讲转义字符之前我们先看一段代码:
#include
int main()
{
printf("c:\code\test.c\n");
//请问这段程序输出结果是什么?是c:\code\test.c吗?
return 0;
}
//答:c:code est.c
为什么输出的是c:code est.c而不是c:\code\test.c呢?这里引入转义字符的概念:
转义顾名思义就是转变意思。上述实例\c、因为c本身不是转义字符,所以输出本身;\t代表水平制表符,所以不输出c:\code\test.c
但是我们可以使用\\来防止它被解释为一个转义序列符:
#include
int main()
{
printf("c:\\code\\test.c\n");
//程序可以正常输出c:\code\test.c
return 0;
}
下附转义字符表:
转义字符 | 释义 |
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\' | 用于表示字符常量' |
\“ | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1~3个八进制的数字。 如: \130 X |
\xdd | dd表示2个十六进制数字。 如: \x30 0 |
注意:\130-表示将8进制数130转换为十进制数 88,然后返回ASCII码值88对应的字符X,同理\x30-表示将16进制数30转换为十进制数48,然后返回ASCII码值48对应的字符’0‘
细心地小伙伴可能发现,这里又涉及到了ASCLL码值的概念,如果对ASCll码比较感兴趣的话,可以了解一下ASCII码表:
1、下述代码通过转义字符可以输出单引号、双引号
#include
int main()
{
//问题1:在屏幕上打印一个单引号',怎么做?
//问题2:在屏幕上打印一个字符串,字符串的内容是一个双引号“,怎么做?
printf("%c\n", '\'');
printf("%s\n", "\"");
return 0;
}
2、 一道笔试题:程序输出什么?
//程序输出什么?
#include
#include
int main()
{
printf("%d\n", strlen("abcdef"));
// \62被解析成一个转义字符
printf("%d\n", strlen("c:\test\628\test.c"));
return 0;
}
//注意:八进制数不含8
//分别是:c,:,\t,e,s,t,\62,8,\t,e,s,t,.,c
//答:输出14
注意:转义字符整体算作1个字符
说回注释,其实大家也能看到,从博文开始,博主的代码中一直都在使用注释,其实注释的作用主要有两点:
1. 代码中有不需要的代码可以直接删除,也可以注释掉
2. 代码中有些代码比较难懂,可以加一下注释文字,便于自己遗忘也便于他人理解
1、C语言风格的注释 /*xxxxxx*/
缺陷:不能嵌套注释
2、C++风格的注释 //xxxxxxxx
可以注释一行也可以注释多行
相比之下,C++更有优势,因此建议使用C++风格的注释
由于篇幅过长、剩下的就放在下期讲解了,如果本文对你有所帮助的话,请给博主一个一键三连哦