一、 什么是C语言
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易 的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。 尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的 C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。 二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制 定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。 [1] 目前2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。 C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。 其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。
二、入门第一个程序
include<stdio.h>
int main()
{
printf(" Hello bit\n");
return 0;
}
2.1分析第一个C语言程序
-
include<stdio.h>意思是引用名为stdio的一个头文件。 .h——表示头文件 .c——表示源文件 -
main() 为主函数,是程序的入口,main在一个程序中有且仅有一个。 int 是整形的意思。 main前面的int表示函数调用返回一个整型值。 -
printf(“Hello bit\n”); printf()为一个输出函数,打印文本。 -
return 0; 程序返回0
三、数据类型
3.1C语言中的数据类型
在了解了第一个程序后,接下来我们了解一下数据类型,那C语言中有那些数据类型呢? 在C语言中有以下数据类型 char //字符数据型 short //短整型 int //整型 long //长整型 long long //更长的整型 float //单精度浮点型 double //双精度浮点型(小数称为浮点型)
3.2 数据类型的区分
那这时我们就会有所疑问C语言为什么会有数据类型的区分呢? 语言的数据类型需要区别开来主要是因为分配内存的不同,同时也是为了更加丰富的表达生活中的各种值。 既然每种数据类型所分配的内存都不一样,那么这些数据类型所占的内存分别是多少呢? 在32位操作系统下这些数据类型所占的内存为: char //1 byte short //2 byte int //4 byte long //4 byte (大于int) long long //8 byte float //4 byte double //8 byte 当然我们也可以用代码来检测
#include <stdio.h>
int main()
{
printf("%d\n", sizeof(char));
printf("%d\n", sizeof(short));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(long));
printf("%d\n", sizeof(long long));
printf("%d\n", sizeof(float));
printf("%d\n", sizeof(double));
printf("%d\n", sizeof(long double));
return 0; }
上面这段代码中运用到了sizeof()这一个操作符,它计算的是变量/类型所占空间的大小,单位是字节,值得注意的是它是一个操作符而不是一个函数; 认识了sizeof(),那么我们来认识strlen()这一个函数,**它是用来计算字符串长度的,**同时在用到strlen()时需要引用一个<string.h>的同文件。
四、常量 变量
4.1 常量和变量的定义
生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等) 有些值是可变的(比如:年龄,体重,薪资)。 不变的值,C语言中用常量的概念来表示,变得值C语言中用变量来表示。 那在C语言中如何定义变量呢? 如下:
int age = 150;
float weight = 45.5f;
char ch = 'w';
4.2 全局变量与局部变量
同时变量又可以分为全局变量和局部变量 那局部变量和全局变量怎么区分呢? 局部变量指的是在函数内定义的变量,全局变量指的是在函数外定义的变量。 我们先来看一段代码
#include <stdio.h>
int y = 1;
int main()
{
int x = 2;
return 0;
}
在上面这段代码中,y是全局变量,x是局部变量
- 局部变量的作用域是变量所在的局部范围。
- 全局变量的作用域是整个工程。
(变量内容过多这里不多于介绍,后面会出一篇关于局部变量和全局变量的博客。)
4.3 常量
C语言中的常量和变量的定义的形式有所差异。 C语言中的常量分为以下以下几种:
- 字面常量
- const 修饰的常变量
- #define 定义的标识符常量
- 枚举常量
#include <stdio.h>
enum Sex
{
MALE,
FEMALE,
SECRET
};
int main()
{
3.14;
1000;
const float pai = 3.14f;
pai = 5.14;
#define MAX 100
printf("max = %d\n", MAX);
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
return 0;
}
上面例子上的 pai 被称为 const 修饰的常变量, const 修饰的常变量在C语言中只是在语法层面限制了 变量 pai 不能直接被改变,但是 pai 本质上还是一个变量的,所以叫常变量。
五、字符串+转义字符+注释
5.1 字符串
什么是字符串呢?
"hello bit.\n"
这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符 串。 注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串 内容。
#include <stdio.h>
int main()
{
char arr1[] = "bit";
char arr2[] = {'b', 'i', 't'};
char arr3[] = {'b', 'i', 't', '\0'};
printf("%s\n", arr1);
printf("%s\n", arr2);
printf("%s\n", arr3);
return 0; }
打印结果如下: 为什么会这样呢? 因为字符串的结束标志是’/0’,在打印arr1[ ] 和 arr3[ ]时当遇到’/0’就会停下来,而在打印arr2[ ]时,当打印到字符’t’之后再往下打发现没有遇到’/0’所以就会继续往后打,直到遇到’/0’才会停下来,至于什么时后会遇到’/0’我们并不知道。因为字符’t’之后都是随机值。
5.2 转义字符
加入我们要在屏幕上打印一个目录: c:\code\test.c 我们该如何写代码?
#include <stdio.h>
int main()
{
printf("c:\code\test.c\n");
return 0; }
打印的结果如下: 为什么打印结果不是“c:\code\test.c\n”呢? 因为在C语言中有转义字符这一定义,转义字符顾名思义就是转变意思。 那有哪些转义字符呢?
转义字符 | 释义 |
---|
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 | \’ | 用于表示字符常量’ | \“ | 用于表示一个字符串内部的双引号 | \\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符 | \a | 警告字符,蜂鸣 | \b | 退格符 | \f | 进纸符 | \n | 换行 | \r | 回车 | \t | 水平制表符 | \v | 垂直制表符 | \ddd | ddd表示1~3个八进制的数字。 如: \130 X | \xdd | dd表示2个十六进制数字。 如: \x30 0 |
5.4 注释
- 代码中有不需要的代码可以直接删除,也可以注释掉
- 代码中有些代码比较难懂,可以加一下注释文字
比如:
#include <stdio.h>
int Add(int x, int y) {
return x+y; }
int main()
{
printf("%d\n", Add(1, 2));
return 0; }
注释有两种风格: C语言风格的注释 / * xxxxxx * / 缺陷:不能嵌套注释 C++风格的注释 //xxxxxxxx 可以注释一行也可以注释多行
六、选择语句 循环语句
6.1选择语句
选择语句有那些呢? 在C语言中的选择语句有:if语句和switch语句。 if语句的执行步骤是先计算圆括号内表达式的值,如果表达式的值非零,则结果为真,执行圆括号后面的语句。 if语句有三种形式
-
if() if(表达式) { 执行的语句; } -
if()—else if(表达式) { 执行的语句; } else//如果if括号中不满足条件,则程序就执行else{}里面的程序 { 执行的语句; } -
if()—else if()—else if(表达语句) { 执行的语句; } else if(表达语句)//如果if括号中不满足条件 //else if()括号中满足条件,则程序就执行else if{}里面的程序 { 执行的语句; } else //如果if() else if()中不满足条件,则执行else{}中的语句 { 执行的语句; } 在了解了if语句的三种形式,那么我们试着用代码实现一下,思维导图如下: 如果你好好学习,校招时拿一个好offer,走上人生巅峰。 如果你不学习,毕业等于失业,回家卖红薯。 这就是选择! 代码演示:
#include <stdio.h>
int main()
{
int coding = 0;
printf("你会去敲代码吗?(选择1 or 0):>");
scanf("%d", &coding);
if(coding == 1)
{
printf("坚持,你会有好offer\n");
}
else
{
printf("放弃,回家卖红薯\n");
}
return 0; }
在了解了if语句后我们再来了解一下switch语句 switch语句表达如下: switch(判断语句) { case 0: 执行的语句; break; case 1: 执行的语句; break; ………… default: 执行的语句; break; } 在Switch中,每执行一个语句后面必须跟有break,否则就会按照顺序往下执行下一个语句。 代码演示:
#include <stdio.h>
int main()
{
int coding = 0;
printf("你会去敲代码吗?(选择1 or 0):>");
scanf("%d", &coding);
switch()
{
case 0:
printf("放弃,回家卖红薯\n");
break;
case 1:
printf("坚持,你会有好offer\n");
break;
}
}
6.2、循环语句
在C语言中有几种循环语句呢? 在C语言中的循环语句有:while语句、for语句、do … while语句。 for (循环变量类型 循环变量名称;循环条件;更新语句) { 执行语句; } which(判断语句) { 执行语句; } 在while中,break直接跳出该循环,continuei则是不执行continuei后面的语句,跳到循环的判断部分
do { }while(判断); do while语句中最少执行一次,然后再进行判断
七、函数
那在C语言中什么是函数呢? 函数在许多程序设计语言中,可以将一段经常需要使用的代码封装起来,在需要使用时可以直接调用,这就是程序中的函数。函数的特点就是简化代码,代码复用。 函数也分为自定义函数和C语言内部函数。 内部函数如:printf、scanf等等。 下面我们演示的是自定义函数。 代码演示:
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("sum = %d\n", sum);
return 0; }
上述代码,写成函数如下:
#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 = %d\n", sum);
return 0; }
上述的代码中Add就是我们自定义的一个函数。
八、数组
8.1、数组定义
在C语言中要存储1-10的数字,怎么存储呢?
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
C语言中给了数组的定义:一组相同类型元素的集合
8.2、数组的下标
C语言规定:数组的每个元素都有一个下标,下标是从0开始的。 数组可以通过下标来访问的。
int arr[10] = {0};
8.3、函数的使用
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(i=0; i<10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0; }
九、操作符
在C语言中操作符有: 算术操作符:
+ - * / %
移位操作符:
>> <<
位操作符:
& ^ |
赋值操作符:
= += -= *= /= &= ^= |= >>= <<=
单目操作符:
>! 逻辑反操作
/ - 负值
/+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等
逻辑操作符:
&& 逻辑与
|| 逻辑或
条件操作符:
exp1 ? exp2 : exp3
逗号表达式:
exp1, exp2, exp3, …expN
下标引用、函数调用和结构成员
[] () . ->
十、常见关键字
在C语言中的常见关键字如下:
auto break case char const continue default do double else enum
extern float for goto if int long register return short signed
sizeof static struct switch typedef union unsigned void volatile while
这里不一 一的介绍。
十一、#define 定义常量和宏
define是一个预处理命令,他有两个用途 1.define定义符号
#define MAX 1000
#include <stdio.h>
int main()
{
printf("%d\n", MAX);
return 0;
}
打印结果就是为1000; 2. define定义宏
#define ADD(x, y) ((x)+(y))
#include <stdio.h>
int main()
{
printf("%d\n", ADD(2, 3));
return 0;
}
打印结果:
值得注意的是define定义宏是替换的,如上面代码中的ADD是被替换成((x)+(y))的。 我们再来看一段代码就能理解了
#define ADD(x, y) x+y
#include <stdio.h>
int main()
{
printf("sum = %d\n", 4*ADD(2, 3));
return 0;
}
打印的结果: 把((x)+(y))换成x+y之后在打印时乘以4,答案并不是45=20,而是11。为什么呢? define定义宏是替换的,ADD被替换成了x+y,4ADD(2,3)也就是4*2+3。
十二、指针
12.1、内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地 址。 0x00000000、0x00000001、0x00000002…0xFFFFFFFF这些就是内存给每个内存单元进行的编号。 那一个这样的内存单元是多大的空间呢? 在C语言中一个这样的内存单元是一个字节。
变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。 那我们怎么在内存中取出变量的地址呢?
#include <stdio.h>
int main()
{
int num = 10;
#
printf("%p\n", &num);
return 0; }
打印如下: 那地址如何存储,需要定义指针变量。 下面这段内容就是把num的地址放在了p里面,当我们找到p就等于找到了num的地址
int num = 10;
int *p;
p = #
那我们如何通过指针找到num呢?
#include <stdio.h>
int main()
{
int num = 10;
int *p = #
*p = 20;
printf("%d\n",num);
return 0; }
那打印的结果如下: 为什么num会变成了20呢? 因为num把自己的地址给了p,*p就是通过p里面的地址找到num,*p=20相当于a=20;
12.2 指针变量的大小
在C语言中指针变量的大小取决于地址的大小 那地址的大小又是多少呢? 在32位平台下地址是32个bit位(即4个字节) 在64位平台下地址是64个bit位(即8个字节) 代码演示:
int main()
{
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(short *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(double *));
return 0; }
当前编译器处在32位平台下
十三、 结构体
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。 结构体可以让C语言创建新的类型出来。 比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。 这里只能使用结构体来描述了。 例如:
struct Stu
{
char name[20];
int age;
char sex[5];
char id[15];
};
int main()
{
struct Stu s = {"张三", 20, "男", "20180101"};
printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id);
struct Stu *ps = &s;
printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps- >id);
return 0;
}
打印结果: 注:结构体是指由一系列具有相同类型或不同类型的数据构成的数据集合。 数组是一组相同类型元素的集合。
|