第一个C程序
#include <stdio.h>
int main()
{
//这是第一个C语言代码
printf("hello world\n");
return 0;
}
分步编译
预处理:gcc -E hello.c -o hello.i
编 译:gcc -S hello.i -o hello.s
汇 编:gcc -c hello.s -o hello.o
链 接:gcc hello.o -o hello
一步编译
gcc hello.c
-o
demo
变量
1. 为什么
现实世界 <----变量---->计算机世界
2. 如何定义
#include <stdio.h>
int main()
{
int a = 10; //定义了一个变量,其类型为int,名字叫a
printf("%d\n", a); //打印变量a的值
return 0;
}
2.1数据类型
数据类型的作用:编译器预算对象(变量)分配的内存空间大小。
2.2变量名
-
标识符
-
命名规则:
- 标识符不能是关键字
- 标识符只能由字母、数字、下划线组成
- 第一个字符必须为字母或下划线
- 标识符中字母区分大小写
//声明
int num ;
float f ;
//定义
int num = 10;
int num;
num =10
声明变量不需要建立存储空间
定义时需要
#include <stdio.h>
int main()
{
int a ; //定义了一个变量,其类型为int,名字叫a
printf("%d\n", a); //打印变量a的值
return 0;
}
#include <stdio.h>
int main()
{
int a = 10; //定义了一个变量,其类型为int,名字叫a
printf("%d\n", a); //打印变量a的值
return 0;
}
/*第一个运行错误*/
2.3值
/*
1 --->整数
1.0 --->浮点数
*/
注意
;
号
详解整型
整型变量的输出
#include <stdio.h>
int main()
{
//有符号
int a = 123; //定义变量a,以10进制方式进行赋值
int b = 0456; //定义变量b,以8进制方式进行赋值
int c = 0xabc; //定义变量c,以16进制方式进行赋值
//格式化输出
printf("a = %d\n", a);
printf("8进制:b = %o\n", b);
printf("10进制:b = %d\n", b);
printf("16进制:c = %x\n", c);
printf("16进制:c = %X\n", c);
printf("10进制:c = %d\n", c);
//无符号
unsigned int d = 0xffffffff; //定义无符号int变量d,以16进制方式赋值
printf("有符号方式打印:d = %d\n", d);
printf("无符号方式打印:d = %u\n", d);
return 0;
}
/*
a = 123
8进制:b = 456
10进制:b = 302
16进制:c = abc
16进制:c = ABC
10进制:c = 2748
有符号方式打印:d = -1
无符号方式打印:d = 4294967295
*/
打印格式 | 含义 |
---|---|
%d | 输出一个有符号的10进制int类型 |
%o(字母o) | 输出8进制的int类型 |
%x | 输出16进制的int类型,字母以小写输出 |
%X | 输出16进制的int类型,字母以大写输出 |
%u | 输出一个10进制的无符号数 |
关于有符号与无符号的区别省略
关于占位符的解释
其他整型
数据类型 | 占用空间 |
---|---|
short(短整型) | 2字节 |
int(整型) | 4字节 |
long(长整形) | Windows为4字节,或8字节 |
long long(长长整形) | 8字节 |
打印格式 | 含义 |
---|---|
%hd | 输出short类型 |
%d | 输出int类型 |
%ld | 输出long类型 |
%lld | 输出long long类型 |
%hu | 输出unsigned short类型 |
%u | 输出unsigned int类型 |
%lu | 输出unsigned long类型 |
%llu | 输出unsigned long long类型 |
sizeof关键字
sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个数据类型的大小,单位为字节
#include <stdio.h>
int main()
{
printf("%ld\n",sizeof(short));
printf("%ld\n",sizeof(int));
printf("%ld\n",sizeof(long));
printf("%ld\n",sizeof(double));
printf("%ld\n",sizeof(float));
printf("%ld\n",sizeof(char));
return 0;
}
详解字符型
-
字符型变量用于存储一个单一字符,在 C 语言中用 char 表示,其中每个字符变量都会占用 1 个字节。在给字符型变量赋值时,需要用一对英文半角格式的单引号(’ ')把字符括起来
-
char的本质就是一个1字节大小的整型
占位符:%c
#include <stdio.h>
int main()
{
char ch = 'a';
printf("sizeof(ch) = %u\n", sizeof(ch));
printf("ch[%%c] = %c\n", ch); //打印字符
printf("ch[%%d] = %d\n", ch); //打印‘a’ ASCII的值
char A = 'A';
char a = 'a';
printf("a = %d\n", a); //97
printf("A = %d\n", A); //65
printf("A = %c\n", 'a' - 32); //小写a转大写A
printf("a = %c\n", 'A' + 32); //大写A转小写a
ch = ' ';
printf("空字符:%d\n", ch); //空字符ASCII的值为32
printf("A = %c\n", 'a' - ' '); //小写a转大写A
printf("a = %c\n", 'A' + ' '); //大写A转小写a
return 0;
}
转义字符
关于
\n
与其他扩展转义字符
\
转义字符 | 含义 | ASCII码值(十进制) |
---|---|---|
\a | 警报 | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\ | 代表一个反斜线字符"" | 092 |
’ | 代表一个单引号(撇号)字符 | 039 |
" | 代表一个双引号字符 | 034 |
? | 代表一个问号 | 063 |
\0 | 数字0 | 000 |
\ddd | 8进制转义字符,d范围0~7 | 3位8进制 |
\xhh | 16进制转义字符,h范围0~9,a~f,A~F | 3位16进制 |
详解浮点型(实型)
单精度浮点数(float)、 双精度浮点数(double), 但是double型变量所表示的浮点数比 float 型变量更精确
不以f结尾的常量是double类型,以f结尾的常量(如3.14f)是float类型
关于隐式转化
#include <stdio.h>
int main()
{
float a = 3.14f; //或3.14F
double b = 3.14;
printf("a = %f\n", a);
printf("b = %lf\n", b);
//科学法赋值
a = 3.2e3f; //3.2*1000 = 3200,e可以写E
printf("a1 = %f\n", a);
a = 100e-3f; //100*0.001 = 0.1
printf("a2 = %f\n", a);
a = 3.1415926f;
printf("a3 = %f\n", a); //结果为3.141593
return 0;
}
关于字符串
- 字符串是内存中一段连续的char空间,以
'\0'
(数字0)结尾。
关于定义会涉及数组,往后会提到,先搂一眼
运算符
运算符类型 | 作用 |
---|---|
算术运算符 (++,–) | 用于处理四则运算 |
赋值运算符 | 用于将表达式的值赋给变量 |
比较运算符 (关系运算符) | 用于表达式的比较,并返回一个真值或假值 |
逻辑运算符 | 用于根据表达式的值返回真值或假值 |
位运算符 | 用于处理数据的位运算 |
sizeof运算符 | 用于求字节数长度 |
条件运算符 | 用于简写if条件判断 |
优先级自己看书吧
- ()
前置++,后置++
–同理
关于类型转化
-
自动转换(隐式转换):遵循一定的规则,由编译系统自动完成。
-
强制类型转换:把表达式的运算结果强制转换成所需的数据类型,利用
()
(类型说明符) (表达式)
//强制类型转化
#include <stdio.h>
int main()
{
float x = 0;
int i = 0;
x = 3.6f;
//跟编译器有关
//i = x; //x为实型, i为整型,直接赋值会有警告
i = (int)x; //使用强制类型转换
printf("x=%f, i=%d\n", x, i);
return 0;
}
//隐式类型转化
#include <stdio.h>
int main()
{
int num = 5;
printf("s1=%d\n", num / 2);
printf("s2=%lf\n", num / 2.0); //默认转化为double
return 0;
}
流程结构
- 顺序结构:程序按顺序执行,不发生跳转。
- 选择结构:依据是否满足条件,有选择的执行相应功能。
- 循环结构:依据条件是否满足,循环多次执行某段代码。
1. 顺序结构(自上而下执行)
2. 选择结构
2.1 if语句
if(判断条件){语句}
判断条件为真时,进入(执行)
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
//比较a与b,a大输出a,b大输出b
if (a > b){
printf("%d\n", a);
}
if (a < b){
printf("%d\n", b);
}
if (a = b){
printf("%d\n", b);
}
return 0;
}
2.2 if…else语句
if(){}else{}
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
if (a > b){
printf("%d\n", a);
}
else{
printf("%d\n", b);
}
return 0;
}
2.3 if…else if…else语句
if(){}else if(){}…else{}语句
#include <stdio.h>
int main()
{
unsigned int a;
scanf("%u", &a);
//判断a的范围
if (a < 10){
printf("个位\n");
}
else if (a < 100){
printf("十位\n");
}
else if (a < 1000){
printf("百位\n");
}
else{
printf("很大\n");
}
return 0;
}
2.4 三目运算符
条件判断?表达式1:表达式2
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int c;
//用if实现
if (a > b){
c = a;
}
else{
c = b;
}
printf("c1 = %d\n", c);
//
c = ( a > b ? a : b );
printf("c2 = %d\n", c);
return 0;
}
/*
c1 = 20
c2 = 20
*/
2.5 switch语句
switch(参数){case 表达式: 语句; break; default: 语句}
#include <stdio.h>
int main()
{
char c = 1;
//参数只能是整型变量
switch (c) {
case '1':
printf("是个1\n");
break;//switch遇到break就中断了
//若没有break会进行穿透
case '2':
printf("是个2\n");
break;
default://如果上面的条件都不满足,那么执行default
printf("什么东西?\n");
}
return 0;
}
考虑没有break的情况
3. 循环结构
while语句
while(表达式){语句}
#include <stdio.h>
int main()
{
int a = 20;
while (a > 10){
scanf("%d", &a);
printf("a = %d\n", a);
}
return 0;
}
do…while语句
do(表达式){}while
#include <stdio.h>
int main()
{
int a = 1;
do{
a++;
printf("a = %d\n", a);
} while (a < 10);
return 0;
}
区别:
先判断后循环,先循环后判断
for语句 (重要)
#include <stdio.h>
int main()
{
int i;
int sum = 0;
for (i = 0; i <= 100; i++){
sum += i;
}
printf("sum = %d\n", sum);
return 0;
}
详细讲解for
关于省略,省略初始条件,循环判断,循环体,一定要有退出条件
关于跳转
break、continue、goto(了解)
End: 语句;
goto End;
#include<stdio.h>
int main()
{
int sum = 0; //定义变量sum
for (int i = 1; i <= 100; i++){
if (i % 2 == 0){ //如果i是一个偶数,执行if语句中的代码
continue; //结束本次循环
}
sum += i; //实现sum和i的累加
}
printf("sum = %d\n", sum);
return 0;
}
数组
-
把具有相同类型的若干变量按有序形式组织起来——称为数组
-
数组是连续的内存空间
1. 数组定义与初始化
- 声明:
数据类型 数组名[长度]
- 通过下标访问
#include <stdio.h>
int main()
{
int a[10];//定义了一个数组,名字叫a,有10个成员,每个成员都是int类型
//a[0]…… a[9],没有a[10]
//初始化
a[0] = 0;
//……
a[9] = 9;
int i = 0;
for (i = 0; i < 10; i++){
a[i] = i; //给数组赋值
}
//遍历数组,并输出每个成员的值
for (i = 0; i < 10; i++){
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
- 初始化
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } 定义一个数组,同时初始化所有成员变量
int a[10] = { 1, 2, 3 } 初始化前三个成员,后面所有元素都设置为0
int a[10] = { 0 } 所有的成员都设置为0
- 可以省略长度,由编译器自动计算
int a[] = { 1, 2, 3, 4, 5 } 定义了一个数组,有5个成员
关于下标越界
2. 关于数组名
- 数组名是一个地址的常量,代表数组中首元素的地址
#include <stdio.h>
int main()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printf("a = %p\n", a);
printf("&a[0] = %p\n", &a[0]);
int n = sizeof(a); //数组占用内存的大小,10个int类型,10 * 4 = 40
int n0 = sizeof(a[0]);//数组第0个元素占用内存大小,第0个元素为int,4
int i = 0;
//将所有元素进行输出,当长度不写时常用此种方法
for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
3. 关于多维数组
类型说明符 数组名[常量表达式1][常量表达式2]
同维数组
在内存中都是一维数组
#include <stdio.h>
int main()
{
//定义了一个二维数组,名字叫a
//由3个一维数组组成,这个一维数组是int [4]
//这3个一维数组的数组名分别为a[0],a[1],a[2]
//常规赋值
int a[3][4];
a[0][0] = 0;
//……
a[2][3] = 12;
//分段赋值
int a[3][4] =
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8, },
{ 9, 10, 11, 12}
};
//连续赋值
int a[3][4] = { 1, 2, 3, 4 , 5, 6, 7, 8, 9, 10, 11, 12};
//利用循环给数组每个元素赋值
int i = 0;
int j = 0;
int num = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
a[i][j] = num++;
}
}
//遍历数组,并输出每个成员的值
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%d, ", a[i][j]);
}
printf("\n");
}
return 0;
}
4. 字符串
- 字符串一定是一个char的数组,但char的数组未必是字符串
数字0(和字符‘\0’等价)结尾的char数组就是一个字符串,但如果char数组没有以数字0结尾,那么就不是一个字符串,只是普通字符数组,所以字符串是一种特殊的char的数组
- 长度利用自动推导
- 占位符:
%s
单字符占位符:
%c
#include <stdio.h>
int main()
{
char c1[] = { 'h', 'e', 'l', 'l', 'o', ' ' }; //普通字符数组
printf("c1 = %s\n", c1); //乱码,因为没有’\0’结束符
//以‘\0’(‘\0’就是数字0)结尾的字符数组是字符串
char c2[] = { 'h', 'e', 'l', 'l', ' ', '\0'};
printf("c2 = %s\n", c2);
//字符串处理以‘\0’(数字0)作为结束符,后面的'h', 'l', 'l', 'e', 'o'不会输出
char c3[] = { 'c', ' ', 'p', 'r', 'o', 'g', '\0', 'h', 'l', 'l', 'e', 'o', '\0'};
printf("c3 = %s\n", c3);
//常用定义
char c4[]="hello";
printf("c4 = %c\n",c4);
return 0;
}
//利用约束
char c5[5]=“hello” //会发生数组越界问题
char c6[6]=“hello”
//区别
函数
1. 函数导入
- printf是输出一个字符串,putchar输出一个char。
打印格式 | 对应数据类型 | 含义 |
---|---|---|
%d | int | 接受整数值并将它表示为有符号的十进制整数 |
%hd | short int | 短整数 |
%hu | unsigned short | 无符号短整数 |
%o | unsigned int | 无符号8进制整数 |
%u | unsigned int | 无符号10进制整数 |
%x,%X | unsigned int | 无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF |
%f | float | 单精度浮点数 |
%lf | double | 双精度浮点数 |
%e,%E | double | 科学计数法表示的数,此处"e"的大小写代表在输出时用的"e"的大小写 |
%c | char | 字符型。可以把输入的数字按照ASCII码相应转换为对应的字符 |
%s | char * | 字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符) |
%p | void * | 以16进制形式输出指针 |
%% | % | 输出一个百分号 |
字符 | 含义 |
---|---|
l(字母l) | 附加在d,u,x,o前面,表示长整数 |
- | 左对齐 |
m(代表一个整数) | 数据最小宽度 |
0(数字0) | 将输出的前面补上0直到占满指定列宽为止不可以搭配使用- |
m.n(代表一个整数) | m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度,用于说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。 |
#include <stdio.h>
int main()
{
double d = 12.3;
printf("d = \' %-10.3lf \'\n", d);
putchar('a');
return 0;
}
/*
d = ' 12.300 '
*/
- scanf函数与getchar函数
getchar是从标准输入设备读取一个char,就是接收一个字符
scanf通过格式化的方式得到用户通过标准输入设备输入的数据
#include <stdio.h>
int main()
{
//变量声明
char ch1;
char ch2;
char ch3;
int a;
int b;
printf("请输入ch1的字符:");
ch1 = getchar();
printf("ch1 = %c\n", ch1);
getchar(); //接收回车键
printf("请输入ch2的字符:");
ch2 = getchar();
printf("\'ch2 = %ctest\'\n", ch2);
getchar(); //接收回车键
printf("请输入ch3的字符:");
scanf("%c", &ch3);//这里第二个参数一定是变量的地址,而不是变量名
printf("ch3 = %c\n", ch3);
printf("请输入a的值:");
scanf("%d", &a);
printf("a = %d\n", a);
printf("请输入b的值:");
scanf("%d", &b);
printf("b = %d\n", b);
return 0;
}
m.n(代表一个整数) | m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度,用于说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。 |
#include <stdio.h>
int main()
{
double d = 12.3;
printf("d = \' %-10.3lf \'\n", d);
putchar('a');
return 0;
}
/*
d = ' 12.300 '
*/
- scanf函数与getchar函数
getchar是从标准输入设备读取一个char,就是接收一个字符
scanf通过格式化的方式得到用户通过标准输入设备输入的数据
#include <stdio.h>
int main()
{
//变量声明
char ch1;
char ch2;
char ch3;
int a;
int b;
printf("请输入ch1的字符:");
ch1 = getchar();
printf("ch1 = %c\n", ch1);
getchar(); //接收回车键
printf("请输入ch2的字符:");
ch2 = getchar();
printf("\'ch2 = %ctest\'\n", ch2);
getchar(); //接收回车键
printf("请输入ch3的字符:");
scanf("%c", &ch3);//这里第二个参数一定是变量的地址,而不是变量名
printf("ch3 = %c\n", ch3);
printf("请输入a的值:");
scanf("%d", &a);
printf("a = %d\n", a);
printf("请输入b的值:");
scanf("%d", &b);
printf("b = %d\n", b);
return 0;
}