一、简单介绍C语言
C语言式目前极为流行的一种计算机程序设计语言,它即有高级语言的功能,又具有汇编语言的一些特点,且支持ANSIC。C语言也是其他众多高级语言的鼻祖语言,所以学习C语言是进入编程世界的必修课。
C语言特点:通用性及易写易读,是一种结构化程序设计语言,具有良好的可移植性,语言功能丰富。
二、第一个C语言程序
1.使用VS2010进行编写,编译C语言代码
2.新建项目:创建一个新项目→添加一个源文件→写代码→编译运行代码
3.新建源文件:源文件xxx.c、头文件xxx.h
#include<stio.h>//头文件
int main()//主函数
{
printf("Hello World\n");//在屏幕上打印输出Hello world
return 0;//函数返回0
}
第一行代码#include<stdio.h>
这句代码引用了一个头文件,表示下面将使用printf函数输出内容,这段代码非常重要,以后每段代码都会用到这个头文件。#include是编译预处理命令,放在源程序的最前面,编译预处理命令后面不加分号。
第二行代码int main(){}
这句代码表示的是主函数的意思,main代表主函数,int是返回类型。一个C语言程序必须有且仅有一个主函数,所以写一个C语言程序,主函数必不可少。C语言程序运行都是从主函数开始的。
第三行代码printf("Hello World\n");
这句代码的意思是在屏幕上打印输出Hello World,而\n表示的是换行的意思。printf()是系统提供的库函数
第四行代码return 0;
这句代码表示的是函数返回0。
三、数据类型
char 字符数据类型
short 短整型
int 整形
long 长整型
long long 更长的整形
float 单精度浮点数
double 双精度浮点数
每种类型所占空间可以用函数sizeof()求得
#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;
}
运行结果:
输出结果位各数据类型的空间大小,单位位字节(type)。1GB=1024MB,1MB=1024KB,1KB=1024type,1type=8bit位
四、初识常量变量
1.常量
常量是在程序的执行过程中其值不变的量。在C语言中,常量不需要类型说明就可以直接使用,常量的类型是由常量本身隐含决定的。从其表现形式上,将常量分为普通常量和符号常量。普通常量就是用数字或字母直接表示的常量;符号常量是用一个标识符来代表的常量。
1.1三类普通常量
800 | 整型数值常量(十进制数)字面常量 |
0666 | 整型数值常量(八进制数,以0开头) |
Ox45,OXFFAA | 整型数值常量,以OX或Ox开头 |
0.2 | 实数数值常量 |
‘a’ | 字符型常量 |
“Hello” | 字符串常量 |
注意:字符串的结束标志是一个\0的转义字符。在计算字符串长度时\0时结束标志,不算作字符内容。%s打印字符串。
1.2字符常量
在C语言程序中,可对常量进行命名,即用符号代替常量,叫做符号常量。用单引号括起来的一个字符,如'a' 就是字符常量。注意,'a’和'A'是两个不同的字符。一般用大写字母表示,符号常量一经定义就可以代替常量使用。
符号常量可以用宏定义#define命令来实现: #define PI 3.1415926 /*定义圆周率*/。
1.3 #define 定义的标识符常量
定义了符号常量PI代表圆周率3.1415926,则在程序中需要使用数据3.1415926时,都可以用PI来代替。
注意:数据在计算机上存储的时候,存储的是2进制,由ASCII编码。
1.4枚举常量enum
枚举就是列举,枚举关键字-enum
C语言关键字表
auto | 声明自动变量 |
short | 声明短整型变量或函数 |
int | 声明整型变量或函数 |
long | 声明长整型变量或函数 |
float | 声明浮点型变量或函数 |
double | 声明双精度变量或函数 |
char | 声明字符型变量或函数 |
struct | 声明结构体变量或函数 |
union | 声明共用数据类型 |
enum | 声明枚举类型 |
typedef | 用以给数据类型取别名 |
const | 声明只读函数 |
unsigned | 声明无符号类型变量或函数 |
signed | 声明有符号类型变量或函数 |
extern | 声明变量是在其他文件正声明 |
register | 声明寄存器变量 |
static | 声明静态变量 |
volatile | 说明变量在程序执行中可被隐含地改变 |
void | 声明函数无返回值或无参数。声明无类型指针 |
if | 条件语句 |
else | 条件语句否定分支 |
switch | 用于开关语句 |
case | 开关语句分支 |
for | 常用的循环语句 |
do | 循环语句的循环体 |
while | 循环语句的循环条件 |
goto | 无条件跳转语句 |
continue | 结束当前循环,开启下一轮循环 |
break | 跳出当前循环 |
default | 开关语句中的“其他”分支 |
sizeof | 计算数据类型长度 |
return | 子程序返回语句(可以带参数,也可以不带参数) |
1.5常见转义字符
字符形式 | 含义 |
\n | 换行符,将光标从当前位置移到下一行的开头。 |
\t | 将光标移到下一位置的水平制表符。 |
\b | 退格符,将光标退回到前一列的位置。 |
\r | 回车符,将光标从当前位置移到本行的开头。 |
\f | 换页,将光标从当前位置移到下一页的开头。 |
\\ | 反斜杠字符(\\)。 |
\' | 单引号字符(')。 |
\" | 双单引号字符(")。 |
\ddd | 1~3位八进制数代表一个字符0~7。 |
\xhh | 1~2位十六进制数代表一个字符。 |
\v | 垂直制表符。 |
\a | 警告字符,蜂鸣。 |
\? | 在书写连续多个问号时使用,防止他们被解析成三个字母语 ??+)。 |
2.变量
变量是指在程序执行过程中,其值可以改变的量。一个变量用一个标识符(变量)表示,在内存中占据一定的存储单元,用于存放变量的值。变量必须向定义后使用,变量的值可以通过赋值的方法获取和改变。
char 1个字节 | 字符数据类型 %C--打印字符格式的数据。 |
short 2个字节 | 短整型 short int。 |
int 4个字节 | 整型 %d--打印整型十进制数据。 |
long 4/8个字节 | 长整型 C语言标准规定 Sizeofl(long)>=Sizeof(int)。 |
long long 8个字节 | 更长整型 (c99)。 |
float 4个字节 | 单精度浮点数 %f--打印浮点数字-打印小数。 |
double 8个字节 | 双精度浮点数。 |
2.1定义变量的方法
1. 全局变量-定义在代码块({})之外的变量。
2. 局部变量-定义在代码块({})内部的变量。
注意:
1. 局部变量和全局变量的名字建议不要相同-容易产生误会,产生bug。
2. 当全局变量和局部变量名字相同时,局部变量优先。
3. C语言法规定,变量要定义在当前代码块的最前面。
2.2 进制之间的转换
字节:计算机中单位bit-比特位 byte-字节 有kb mb gb tb pb。 |
一个字节=8个比特位的大小。 |
二进制由0、1两个数字组成,逢二进一。 |
八进制数由0~7八个数字组成。 |
十六进制数由0~9十个数和A~F(或a~f)六个字母组成,逢十六进一。 |
十进制转二进制:除2取余。 |
十进制转八进制:除8取余。 |
十进制转十六进制:除16取余。 |
二进制转十进制:从二进制最低位开始向高位依次将每一个标识位第0位开始......,以这个位数作为2的幂次方与对应位上的数(0或1)相乘之后累加的和就是其对应的十进制数。 |
八进制数或十六进制数转换为十进制数是将2的幂次方换成8的幂次方或者16的幂次方。 |
八进制转二进制:将每一位八进制转换成一个3位的二进制就可以得到。 |
十六进制数转二进制数:将每一位十六进制数转换为为一个4位的二进制数就可以得到 。 |
3.变量的作用域和生命周期
3.1作用域
含义:变量在哪里起作用,哪里就是它的作用域
局部变量作用域:就是变量所在的局部范围
全局变量的作用域:整个工程
3.2生命周期
变量的生命周期:变量的创建和销毁之间的时间段
局部变量的生命周期:进入局部范围生命开始,出局部范围生命结束
全局变量的生命周期:整个程序的生命周期
五、注释
定义:
1. 代码中又不需要的代码可以直接删除,也可以注释掉。
2. 代码中有些代码比较难懂可以加一下注释文字。
/* | 分格 C语言的分格。 |
*/ | 不能嵌套注释。 |
//(C++) | 可以注释一行也可以注释多行。 |
Ctrl+K+C | 注释。 |
Ctrl+K+U | 取消注释。 |
六、数据的格式化输出和输入
6.1 数据的格式化输出
格式化输出函数printf()的功能是按指定的格式向终端(或系统默认的输出设备)输出若干个任意类型的数据。
printf()函数的一般形式为:printf("格式控制",[输出列表]) |
其中,"格式控制"是用双引号括起来的字符串,也称"转换控制字符串"。它是由字符"%"、格式字符(如d、f、c等)和普通字符(原样输出的)组成。"输出列表"是一些与"格式控制"中的格式字符--对应的需要输出的变量或表达式。
int b=~a; //b是有符号的整形
//原码、反码、补码
//负数在内存中存储的时候,存储的是二进制的补码
printf("%d\n",b);
//使用的打印的是这个数的原码
6.2 原码、反码、补码运算
原码->反码 符号不变其他位按位取反。 |
反码->补码 反码加1得到补码。 |
补码->反码 补码减1 11111->11110。 |
反码->原码 符号不变其它按位取反 11110->10001 开头是1表示负数 ,开头是0的表示正数。 |
在内存中)任何数字存的都是补码。 |
反码只是计算机的一个中间状态。 |
原码->反码->补码 只要是整数,内存中存储的都是二进制数。 |
6.3 数据的格式输入
格式化输入函数scanf()的功能是用来从外部输入设备(通常是键盘),像程序中的变量输入一个或若干个任意类型的数据。
scanf()函数的一般形式为:
scanf(格式控制,地址列表); |
使用scanf()函数时要输入的变量名前要加取地址符号&。其中,”格式控制“的含义同printf()函数;”地址列表“是由若干个地址组成的列表,可以是变量的地址或字符串的首地址。
6.4 单个字符的输出和输入
函数putchar()和getchar()专门用来输出和输入字符型数据,使用时要包含头文件stdio.h。
6.4.1 输出单个字符函数putchar()
putchar()函数的功能是用于将单个字符输出到显示器上,其一般形式为:
putchar(ch); |
6.4.2输入单个字符函数getchar()
getchar()函数的功能是从标准输入设备(键盘)读入一个字符。其一般形式为:
ch=getchar() |
其中,ch为一个字符型变量,把从键盘接收到的字符放到变量ch中。
七、运算符与表达式
7.1单目操作符
单目操作符 | 作用 |
! | 逻辑反操作 假变真 真变假 |
- | 负值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作数的类型长度(以字节为单位)2进制 |
~ | 对一个数的二进制按位取反 |
x-- | 后置--,先使用,再减减 |
--x | 前置--,先减减,再使用 |
x++ | 前置++,先加加,再使用 |
++x | 后置++,先使用,再加加 |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
7.2赋值操作符:+= -= *= /= &= ^= |= >>= <<=
int main()
{
int a = 1;
a = a + 1;
//相当于:
a += 1;
a = a - 2;
//相当于:
a -= 2;
a = a % 3;
//相当于:
a %= 3;
return 0;
}
7.3移位操作符:>>(右移) <<(左移)
移动的是二进制位,以左移操作符为例:
a的值为2,其二进制序列为:
00000000 00000000 00000000 00000010
向左移动一位
0 00000000 00000000 00000000 00000100 //注最左端的移出,最右端补了一个0
补完之后就是100,换算成十进制就是4,所以b=4
注意:十进制2换算成二进制就是10,又因为a是放在整型里,整型是4个字节,一个字节是8个比特位,所以要写成32个比特位。
7.4位操作符:& 按位与 | 按位或 ^ 按位异或
7.5关系操作符
关系操作符 | 名称 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
!= | 不等于 |
== | 等于 |
7.6逻辑操作符
名称 | 作用 |
---|---|
&& 逻辑与 | 两个都为真,才为真 |
|| 逻辑或 | 两个都为假,才为假 |
int main()
{
int a=3;
int b=5;
int c=a&&b;
printf("%d\n",c);//输出1,因为a为真,b为真,两个都为真,所以c为真
return 0;
}
7.7条件操作符(三目操作符):exp1?exp2:exp3;
含义:若exp1成立,则计算exp2,整个表达式结果就是exp2的结果;若exp1不成立,结果为exp3的结果。
int main()
{
int a=0,b=3,max=0;
if(a>b)
max=a;
else
max=b;
//上述if语句和下面一行代码相等
max=a>b?a:b;//a>b若成立,将a的值给max;否则将b的值给max
return 0;
}
7.8逗号表达式:exp1,exp2,exp3,······,expn
含义:逗号隔开的一串表达式,会从左往右依次计算,整个表达式的结果取最右侧表达式的结果
表达式的求解过程:按照从左大有右的顺序逐个求解表达式1,表达式2,...,表达式n的值,而整个逗号表达式的值是最后一个表达式(表达式n)的值 。
7.9下标引用、函数调用和结构成员
7.9.1 [ ] () . ->
[ ]是下标引用操作符
( )是函数调用操作符
7.9.2 **& * . ->**
这四个操作符在接下来课程中再详细讲述
八、初识选择语句&&循环语句
8.1选择语句
int main()
{
int age;
printf("请输入你的年龄:");
scanf("%d",&age);
if(age<18)
{
printf("未成年\n");
}
else
{
printf("已成年\n");
}
return 0;
}
运行结果:
请输入你的年龄:20
已成年
8.2循环语句
int main()
{
int i=0;
while(i<10)
{
printf("%d ",i);
i++;
}
printf("\n");
return 0;
}
运行结果:
0 1 2 3 4 5 6 7 8 9
九、初识函数和数组
9.1函数
int add(int x, int y)//创建整型x和y,来接收传递过来的num1和2//add前面的int是返回值的类型
{
int z = 0;
z = x + y;
return z;//将z的值返回给函数add
}
int main()
{
int num1 = 0, num2 = 0;
printf("输入两个操作数:>");
scanf("%d%d", &num1, &num2);
int sum = add(num1, num2);//将num1和2的值传递给x和y,将函数add的值传递给sum
printf("sum=%d\n", sum);
return 0;
}
9.2数组
要存储1-10的数字,怎么存储?
数组:一组相同类型元素的集合
数组定义:
int arr[10]={1,2,3,4,5,6,7,8,9,10};//定义一个整型数组,这个数组最多放10个元素
char ch[5]={'a','b','c'};//字符型数组,不完全初始化,剩余的默认为0
数组访问规则:数组是由下标来访问的
十、#define定义常量和宏
define是一个预处理指令
10.1 define定义标识符常量
#define MAX 666
int main()
{
printf("%d\n",MAX);//输出666
return 0;
}
10.2 define定义宏
#define ADD(X,Y) X+Y
int main()
{
printf("%d\n",ADD(5,6));//输出11
return 0;
}
#define ADD(X,Y) X+Y //注意:宏定义没有分号
int main()
{
printf("%d\n",4*ADD(5,6));//输出26,而不是44
//4*5+6=26(因为宏是变量的替换)
return 0;
}
加括号可以让宏定义按要求输出结果
#define ADD(X,Y) ((X)+(Y))
int main()
{
printf("%d\n",4*ADD(5,6));//输出44
return 0;
}
十一、指针
11.1内存
内存是计算机中用于存储数据和程序的设备。它是计算机的重要组成部分,用于临时存储数据和指令,以供CPU进行读取和处理。内存通常被分为主存和辅存两种类型。
主存是计算机中直接与CPU进行数据交换的部分,也被称为随机存取存储器(RAM)。它具有较快的读写速度,但是断电后数据会丢失。主存的大小通常以字节为单位来衡量,例如1GB或8GB。
辅存是计算机中用于长期存储数据和程序的设备,例如硬盘驱动器或固态硬盘。辅存的读写速度较慢,但是数据可以长期保存,即使断电也不会丢失。
内存的大小对计算机的性能有重要影响。较大的内存可以容纳更多的数据和程序,从而减少了对辅存的访问次数,提高了计算机的运行速度。因此,对于需要处理大量数据或运行复杂程序的任务,较大的内存是必要的。
为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
为了能够有效地访问到内存的每个单元,就给内存进行了编号,这些编号被称为该内存单元的地址。
理解内存:在现实生活中,给每个空间都编了一个有效的地址,就可以精确地找到一个房间;对于内存也是一样的。
电脑有32位和64位,32位就是32位地址线→是物理线→通电→有1、0两种状态
然后电信号转换成数字信号:1和0组成的二进制序列
32位从全0变成全1,会有2^32个地址
那么一个32位的内存单元多大呢:4294967296 bit /8=536870912 byte /1024=524288 kb/1024=512MB /1024=0.5GB
bit比特*8=byte字节 *1024=kb *1024=MB *1024=GB *1024=TB *1024=PB
由于一个比特位是一个内存空间,管理的内存空间太少,因此最终取一个内存单元是一个字节,然后分配地址
int main()
{
int a = 10;//a在内存中要分配空间的--4个字节
printf("%p\n", &a);//%p专门用来打印地址的
//&a是a的地址,地址也是要存放在内存里的
int* pa = &a;//pa是用来存放地址的,在c语言中pa叫指针变量
// *说明pa是指针变量
// int说明pa执行的对象是int类型
char ch = 'w';
char* pc = &ch;
return 0;
}
我们用pa存放a的地址,是为了能找到a,使用a,所以需要解引用来找到a
int main()
{
int a =10;
int* pa=&a;//将a的地址存放在pa变量中
*pa=20;// * 是解引用操作 *pa就是通过pa里面的地址,找到a
printf("%d\n",a);//输出20(借助pa实现对a的操作)
return 0;
}
11.2指针变量的大小
若改为64位平台,则输出值为8个字节。
结论:指针的大小在32位平台是4个字节,64位平台是8个字节。
十二、结构体
在C语言中,结构体是一种用户自定义的数据类型,用于存储不同类型的数据项。结构体可以包含多个成员变量,每个成员变量可以是不同的数据类型,如整型、浮点型、字符型等。
结构体的定义使用关键字struct,后跟结构体的名称和成员变量列表。例如,下面是一个表示学生的结构体的定义:
struct Student
{
char name[20];//姓名
int age;//年龄
float gap;//平均成绩
};
上述代码定义了一个名为Student的结构体,它包含了三个成员变量:name、age和id。其中,name是一个字符数组,用于存储学生的姓名;age是一个整型变量,用于存储学生的年龄;gpa是一个浮点型变量,用于存储学生的平均成绩。
我们可以使用结构体类型创建结构体变量,如下所示:
struct Student s1;
上述代码创建了一个名为s1的结构体变量,该变量具有Student结构体类型,并且可以存储一个学生的信息。
可以使用点操作符(.)来访问结构体变量的成员变量,如下所示:
strcpy(s1.name, "John");
s1.age = 20;
s1.gpa = 3.5;
上述代码将字符串"John"复制给s1的name成员变量,将整数20赋值给s1的age成员变量,将浮点数3.5赋值给s1的gpa成员变量。
结构体还可以作为函数的参数和返回值,以便在不同的函数之间传递和操作结构体数据。