初识C语言(1)
目录
前言
大多数人在高中时期曾接触过python编程语言,但相信大家都只是在计算机课上打打游戏,看看剧,并没有真正认真了解了这一门编程语言。进入大学之后,大家首先遇到的就是c语言,可以说c生万物,学好c语言才能打好基础,才能更好的学习c++和java。因此本篇博客将零基础粗略介绍c语言的相关内容。可以对c语言有个大概的了解,在今后的博客中,再对这些知识点分门别类的详细讲解。
什么是c语言
c语言言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易 的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。 [1] 目前2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11。
C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。 其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。
输入输出
c语言中运用了printf和scanf进行标准输入输出。意思就是从键盘上输入,从屏幕上输出,后续还有从文件中进行输入输出。
#include<stdio.h>
int main()
{
int a;
scanf("%d",&a);
printf("%d",a);
return 0;
}
这里的%d的意思是整形格式,&是取地址符,scanf是从键盘中获取存入到a中,printf是从a获取打印到屏幕中。
数据类型
生活中随处可见小数,正数,和字母,c语言是一门严谨的语言,在存储中不同的数据类型运用了不同的存储方式。
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数
上述代码中的字符数据类型是存储诸如a,b,c...等字母的,整形是存储正数,不同长度的整形可以存储不同大小的正数,浮点数就是小数,双精度和单精度的区别就是小数点后的位数变得更多了。
计算机中各个数据类型所占的空间大小是多少呢,值得一提的是,计算机中最小的单位是比特,然后是字节,一字节等于8比特,1kb = 1024bit,1mb = 1024kb,1gb = 1024mb,1tb = 1024gb。再往上就是PB、EB、ZB、YB、BB、NB、DB、CB。那么,我们通过一下代码来求出各个数据类型所占的空间大小
#include <stdio.h>
int main() {
printf("%dn", sizeof(char)); //1
printf("%dn", sizeof(short)); //2
printf("%dn", sizeof(int)); //4
printf("%dn", sizeof(long)); //4
printf("%dn", sizeof(long long)); //8
printf("%dn", sizeof(float)); //4
printf("%dn", sizeof(double)); //8
return 0;
}
(%d是用来打印整形数据类型的)
上述代码中后面的注释数字便是每个数据类型所占的空间大小,这个是在32位编译器下的运行结果,单位是字节。
有了这些数据类型,我们便可以定义一些生活中常见的变量,来编写我们的代码。那么什么是变量,什么又是常量呢??
变量和常量
在c语言中,可变的量就是变量,需要在使用前先进行声明,不变的量就是常量。
定义变量的方法:
int age = 150;
float weight = 45.5f;
char ch = 'w';
在c语言中,变量也有不同的分类,可以分为全局变量和局部变量。我们在每一个函数中定义的(包括main函数)都是局部变量,而其他的便是全局变量
#include <stdio.h>
int global = 2019;//全局变量
int main()
{
int local = 2018;//局部变量
int global = 2020;//局部变量
printf("global = %dn", global);
return 0;
}
可以看到,我们的global既在全局中有变量,也在局部中有变量,在这种情况下,global的定义也是没有问题的,我们将在使用时优先使用局部变量。
变量的作用域和生命周期
一个变量并不总是可用的,他的值也不是一直存在的。一个变量出了他的作用域,便结束了他的生命周期,而他的作用域就是包揽他的最近的两个大括号之中。当然,全局变量没有大括号,那么全局变量的作用域就是你所创建的这个工程的全部。在工程结束时,全局变量的生命周期才会结束。这个的主要考点在函数的使用上会有所体现,在今后的博客中将一一讲解。
常量
常量也有不同的分类:
字面常量
直接在程序中使用的数字就是字面常量。
const 修饰的常变量
变量前加了const,那么这个变量的值就是无法修改的了。
#define 定义的标识符常量
运用#define MAX 100,这个意思就是在今后程序中但凡出现了MAX的地方,在编译时
都将他替换成100使用
枚举常量
生活中常见一些量是我们可以直接枚举出来的,那么这时可以使用enum。在此枚举
中,从上到下依次将被赋值为0,1,2... 在下列编码中,sex枚举了male,female,
secret。那么在今后的使用中,默认male的值是0,female是1,secret是2。
#include <stdio.h>
//#define的标识符常量 演示
#define MAX 100
//枚举常量演示
enum Sex
{
MALE,
FEMALE,
SECRET
};//括号中的MALE,FEMALE,SECRET是枚举常量
int main()
{
//字面常量演示
3.14;//字面常量
1000;//字面常量
//const 修饰的常变量
const float pai = 3.14f;
pai = 5.14;//是不能直接修改的!
printf("%dn", MALE);
printf("%dn", FEMALE);
printf("%dn", SECRET);
printf("max = %dn", MAX);
return 0;
}
字符串
由于c语言中只有字符数据类型,而没有字符串数据类型,因此我们运用双引号将一系列字符扩起来的这种方法来表示字符串
"hello world"
字符串的结束标志是一个 的转义字符。在计算字符串长度的时候 是结束标志,不算作字符串 内容。
#include <stdio.h>
int main()
{
char arr1[] = "bit";
char arr2[] = {'b', 'i', 't'};
char arr3[] = {'b', 'i', 't', ''};
printf("%sn", arr1);//bit
printf("%sn", arr2);//随机
printf("%sn", arr3);//bit
return 0;
}
(%s 是输出字符串专用格式)
可见,上述代码中,我们的字符串在输出时候必须要么是连续的,要么后面是有的,否则将会输出随机值
因此,我们运用strlen这个函数求字符串长度时是不算的,但是在运用sizeof这个函数计算字符串所占空间大小的时候,是需要计算的。
转义字符
在电脑中我们不仅需要输出各种数据类型,同样还要输出诸如回车,tab这样的特殊形式,因此c语言中使用了转义字符来输出这些特殊的字符。
转义字符 释义
? 在书写连续多个问号时使用,防止他们被解析成三字母词
' 用于表示字符量'
“ 用于表示一个字符串内部的双引号
\ 用于表示一个反斜杠,防止它被解释为一个转义序列符。
a 警告字符,蜂鸣(许多电脑可能不支持)
b 退格符(相当于删除一个字符)
f 进纸符
n 换行
r 回车
t 水平制表符(tab键)
v 垂直制表符
ddd ddd表示1~3个八进制的数字。如: 130 X
xdd dd表示2个十六进制数字。 如: x30 0
值得说明的是,现在许多编译器中都已经取消了三字母词。ddd 例如 130就是在使用时将130这个8进制数字转换为十进制数字使用,并找到这个十进制数字所对应的是ascii码表中相对应的字符。
有了这些转义字符,我们就可以运用它们来打印一些希望得到的输出
#include <stdio.h>
int main()
{
printf("%cn", ''');//打印单引号
printf("%sn", """);//打印双引号
return 0;
}
#include <stdio.h>
int main() {
// 62被解析成一个转义字符
printf("%dn", strlen("c:test628test.c"));//14
return 0;
}
因为628转换为十进制后大大超出了ascii码表的范围,因此在转义时62相当于一个字符,t相当于是一个字符。因此这个代码的输出结果是14。
注释
注释有两种风格:
C语言风格的注释 /*xxxxxx*/ 缺陷:不能嵌套注释
C++风格的注释 //xxxxxxxx 可以注释一行也可以注释多行
良好的代码风格需要添加注释来对代码的内容进行解读。在公司中,别人有可能接手你的代码,你也有可能接手别人的代码,而对于同一件事物,我们的定义变量的名字有所差异,我们的代码用途有所不同,需要多添加注释使得代码的可读性提高。
选择语句
生活中没有一马平川的事情,处处充满了选择,而c语言中有两种选择语句,在这篇博客中先粗略介绍if else语句,在之后的文章中再对其和swich case语句进行详细的讲解。
#include <stdio.h>
int main()
{
int coding = 0;
printf("你会去敲代码吗?(选择1 or 0):>");
scanf("%d", &coding);
if(coding == 1)
{
prinf("坚持,你会有好offern");
}
else
{
printf("放弃,回家卖红薯n");
}
return 0;
}
判断语句中,如果满足if()中的内容的话,那么就进入到其大括号的语句中,反之则跳过一整个大括号。如果下面有else语句时,上面的if语句不满足则直接进入else语句的大括号中。值得一提的是,可以只使用if而不使用else,但不可以只有else而没有if。如果if里面的语句只有一句时,可以省略大括号,但最好加上,使得代码的可读性更好。在有多种选择时,使用if,else if,else这种语句。如果不满足if和else if时,进入else语句中,else if语句可以有一到多个。
循环语句
同样,生活中还有许多事情需要反反复复的去完成,那么c语言中相对应的是循环语句有三种,while语句,do while语句,for循环语句。这篇博客先简略介绍一下while循环。
#include <stdio.h>
int main()
{
int line = 0;
while(line<=20000)
{
line++;
printf("我要继续努力敲代码n");
}
if(line>20000);
printf("好offern");
return 0;
}
while循环中如果满足while后面的()时,进入循环,直到不再满足()中的条件,终止循环,因此我们在使用循环时一定要判断好条件,不要形成死循环。跳出循环还有两种方法,break和goto语句,在之后的博客中将一一讲解。
函数
在编写程序的时候我们要高内聚低耦合,意思就是一段代码最好多实现自己的功能而不依赖于别的代码。而一个程序可能由多个程序员来编写,那么难免有一些功能是重复的造成了代码的冗余。因此我们可以把这些功能分装成一些函数,来实现他们的功能。
(main()也是一种函数,名为主函数)
#include <stdio.h>
int Add(int x, int y)
{
int z = x+y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = Add(num1, num2);
printf("sum = %dn", sum);
return 0;
}
在上述代码中我们实现了加法的函数。其中int Add(int x,int y)是对函数的声明,第一个int的意思是我这个函数的返回值是int,也就是z,后面两个int的意思是这个函数要传过来两个int类型的值,也就是x,y。我们通过主函数调用Add函数,传入两个值,再在函数内部计算出结果,返回的值赋给sum,最后在主函数中打印出来sum的值。
数组
如果有一堆相同数据类型的数据需要定义使用,那么将十分麻烦,因此c语言中引用了数据的概念。
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素
一般来说用arr声明数组,在声明数组时,[]中的数字大小代表这个数组最多可以装多少个元素。可以直接写int arr[] = {1,2,3,4,5,6,7,8,9,10};这样的话是自动将数组的大小定为了10。不能前面声明的数字比后面初始化的数字少。
在使用时,数组有一个概念是下标。从第一个元素到最后一个元素,数组的下标从0逐个加一。在使用时arr[0]代表了我要访问数组的第一个元素,也就是1。如果是arr[9],那么我访问的就是第10个元素,也就是10。可以看出,数组的下标总是比数组的元素个数少一。
在数组的初始化时,arr[10] = { 0 }代表的是将数组中的十个元素都初始化为0,
arr[10] = { 1 } 代表的是将数组的第一个元素初始化为1,其他的元素都初始化为0。
操作符
算术操作符
+ - * / %
同数学中的运算,%的意思是取模,等于一个数除以一个数后的余数,比如6%2 = 0,
6%5 = 1。
移位操作符
>> <<
计算机中采用的是二进制位,1>>2代表右移两个二进制位,1<<3代表左移三个。
位操作符
& 按位与 将两个数的二进制位中每一位如果都是1就是1,否则就是0。
1010 & 1001 = 1000
| 按位或 将两个数的二进制位中每一位如果有一个是一就是1,否则是0。
1010 | 1001 = 1011
^ 按位异或 将两个数的二进制位中每一位如果相异为1,相同为0。
1010 ^ 1001 = 0011
赋值操作符
= += -= *= /= &= ^= |= >>= <<=
将等号右边的值进行操作后赋值给前面 a += 3 相当于 a = a + 3
单目操作符
上述操作符都为双目操作符,也就是操作符的对象是操作符的左右两边。
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置-- 先--再使用 先使用再--
++ 前置、后置++ 先++再使用 先使用再++
* 间接访问操作符(解引用操作符) 对指针解引用
(类型) 强制类型转换 (int)3.14 相当于3
关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”(c语言中=用来赋值,==是判断是否相等)
逻辑操作符
&& 逻辑与 两者都为真才为真
|| 逻辑或 一个为真就为真
条件操作符
exp1 ? exp2 : exp3
如果第一个表达式成立就执行第二个表达式,如果不成立就执行第三个
a = 1, b = 2,a>b ? max = a : max = b 执行后max = b = 2
逗号表达式
exp1, exp2, exp3, ...expN
从左到右依次往后求解,表达式的值等于最后一个表达式也就是expN的值
下标引用、函数调用和结构成员
[] 数组的下标访问
() 函数的调用
. 结构体成员的访问
-> 结构体指针的访问