目录
1.字符串
"hello world!"
//字符串 - 一串字符
//字符 - 键盘输入的任何一个值
这种由双引号引起来的一串字符称为字符串字面值,或者简称字符串。 注:下图中字符串的结束标志是一个'\0'的转义字符。在计算字符串长度的时候'\0'是结束标志,不算作字符串的内容。
#include<stdio.h>
#include<string.h>
int main()
{
//字符串 - 一串字符
//字符 - 键盘输入的任何一个值
char arr1[] = "abc";//[a] [b] [c] [\0]
char arr2[] = { 'a','b','c'};//[a] [b] [c] ......
char arr3[]= { 'a','b','c','\0'};//[a] [b] [c] [\0]
//打印字符串 - %s //输出结果
printf("%s\n", arr1); //abc
printf("%s\n", arr2); //abc烫烫烫烫烫烫烫烫烫烫烫烫烫烫蘟bc - ?\
无字符串的结束标志 - '\0' - 从而出现这样的随机值
printf("%s\n", arr3); //abc - 加入'\0'就不会出现错误了
//strlen - 库函数 - 求字符串的长度
//从给定的地址,向后数字符,直到遇到'\0'结束,'\0'不统计在内
printf("%d\n", strlen(arr1));//3
printf("%d\n", strlen(arr2));//35 - 随机值
printf("%d\n", strlen(arr3));//3
return 0;
}
2.转义字符
假如我们要在屏幕上打印一个目录: c:\code\test.c 我们该如何写代码?
#include <stdio.h>
int main()
{
// \t - 制表符 \n - 换行符
printf("c:\code\test.c\n");
// ??) 三字母词
printf("(are you ok??)");
return 0;
}
实际上程序运行的结果是这样的:
1.c:code est.c
2.(are you ok]
为什么呢?因为这些字符存在特殊的意义,所以不能直接打印,从而我们就需要转义字符进行转义,这样我们才能输出我们想要表达的值。
当我们改变一下程序:将特殊含义字符前面加 \
#include <stdio.h>
int main()
{
// \t - 制表符 \n - 换行符
printf("c:\\code\\test.c\n");
// ?// 三字母词
printf("(are you ok\?\?)");
return 0;
}
此时程序运行的结果是这样的:
c:\code\test.c
(are you ok??)
这样就是我们想要的结果啦。
接下来介绍一下C语言常用的转义字符
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\' | 用于表示字符常量' |
\" | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符。 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | d d d表示1~3个八进制的数字。 如: \130 表示字符X |
\xdd | d d表示2个十六进制数字。 如: \x30 表示字符0 |
这里我们介绍一下/ddd和/xdd
#include<stdio.h>
int main()
{
//八进制 130 - 十进制 88 - 对应的ASCII码为 X
printf("%c\n", '\130');// X
//十六进制 x31 - 十进制 49 - 对应的ASCII码为 1
printf("%c\n", 'x31');// 1
return 0;
}
现在让我们来看看自己是否学会了!!!
#include <stdio.h>
int main()
{
//问题1:在屏幕上打印一个单引号',怎么做?
//问题2:在屏幕上打印一个字符串,字符串的内容是一个双引号“,怎么做?
printf("%c\n", '\'');
printf("%s\n", "\"");
return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
printf("%d\n", strlen("c:\test\x22\129\test.c"));
return 0;
}
值为多少呢? ---15
这里有一个坑\129里面的9并不是八进制,所以算两个字符。
3.注释
1. 代码中有不需要的代码可以直接删除,也可以注释掉
2. 代码中有些代码比较难懂,可以加一下注释文字
注释有两种风格:
C语言风格的注释 /*xxxxxx*/ 缺陷:不能嵌套注释
C++风格的注释 //xxxxxxxx 可以注释一行也可以注释多行
#include<stdio.h>
int main()
{
//以 // 开头的注释是属于C++的注释风格
//注释
//int a = 0;
//以 /**/ 开头的注释是属于C语言的注释风格 - 不能嵌套
/*int a = 0;*/
return 0;
}
4.选择语句
1.if -- else if -- else 语句
2.switch -- case -- break 语句
//if - else语句
#include <stdio.h>
int main()
{
int coding = 0;
printf("你会去敲代码吗?(选择1 or 0):>");
scanf("%d", &coding);
if(coding == 1)
{
prinf("坚持,你会有好offer\n");
}
else
{
printf("放弃,回家卖红薯\n");
}
return 0;
}
//switch - case - break
#include<stdio.h>
int main()
{
int coding = 0;
printf("你会去敲代码吗?(选择1 or 0):>");
scanf("%d", &coding);
switch (coding)
{
case 1:
printf("坚持,你会有好offer\n");
break;
case 0:
printf("放弃,回家卖红薯\n");
break;
}
}
5.循环语句
1.for语句
2.while语句
3.do ... while语句
//for语句
#include <stdio.h>
int main()
{
printf("好好学习\n");
int line = 0;
for(line = 0;line <= 20;line++)
{
printf("我要继续努力敲代码\n");
}
if (line > 20)
printf("好offer\n");
return 0;
}
//while语句
#include <stdio.h>
int main()
{
printf("好好学习\n");
int line = 0;
while (line <= 20)
{
line++;
printf("我要继续努力敲代码\n");
}
if (line > 20)
printf("好offer\n");
return 0;
}
//do ... while语句
#include <stdio.h>
int main()
{
printf("好好学习\n");
int line = 0;
do
{
printf("我要继续努力敲代码\n");
line++;
} while (line <= 20);
if (line > 20)
printf("好offer\n");
return 0;
}
6.函数
函数可以理解为一个模块的代码,单独实现一个功能。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Add(int x, int y)
{
int z = x + y;
return z;//z的类型是整型int,返回也为int
}
int main()
{
//函数可以理解为一个模块的代码
//单独实现一个功能
int a = 0;
int b = 0;
int sum = 0;
//输入
scanf("%d %d", &a, &b);
sum = a + b;
sum = Add(a, b);
//输出
printf("%d\n", sum);
return 0;
}
这里我们来看这段代码,求两个数的和,我们采用了直接求和、函数求和两种方法,单凭本程序看,函数求和的写法比直接求和的方法的代码行数明显增多,这里肯定有疑问为什么还要使用函数的方法呢?在这里我们格局要放大,当未来程序特别复杂,某个功能的实现代码量比较多的时候,我们需要多次使用该代码,但是我们总不能每次都写这个功能的代码,这样会使程序量变大,此时,就体现了函数的功能,我们只需要调用该函数就行,非常简洁。
7.数组
当我们要存储一个班上100多位学的成绩,我们该怎么存储呢?此时肯定有人说:肯可以定义一百个变量,存储每个同学的成绩,这种方法确实可以,但是如果我们有1000位,10000位同学的时候呢?这种每个同学都定义一个变量去存储成绩,必然会耗费大量的时间去写我们的代码,那有什么简便方法吗?C语言就为我们提供了数组的定义,它可以定义一组相同类型元素的集合。
#include<stdio.h>
int main()
{
int score1 = 90;
int score2 = 91;
.
.
.
//这样存储显然太麻烦
//数组 - 可以保存一组相同数据类型的集合
//整型数组
int scores[10] = { 90,91,92,93,94,95,96,97,98,99,100 };
//用数组的方式非常容易的存储了10位同学的成绩
//字符数组
char name[10];
return 0;
}
8.数组的下标
有了上述的数组,我们该怎么拿到每个同学的成绩呢?C语言规定:数组的每个元素都有一个下标,下标是从0开始的。 数组可以通过下标来访问的。
比如:
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
// 下标: 0 1 2 3 4 5 6 7 8 9
//要拿到元素5 - 用下标4访问
printf("%d", arr[4]);
//拿到所有元素 - 遍历下标即可
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
9.操作符
算术操作符
+ - * / %
#include<stdio.h>
int main()
{
int x = 10;
int y = 6;
printf("%d\n", x + y);//16
printf("%d\n", x - y);//4
//乘号不能写成 - x
printf("%d\n", x * y);//60
/*
除法 - /
1.计算结果是整除之后得到的商
2.除法有:
整数除法
浮点数除法 - 保证除数和被除数至少有一个是浮点数
取模/取余 %
得到的是余数 - 操作符两边的数都必须是整型
*/
printf("%d\n", x / y);//1
printf("%lf\n",10 / 6.0);//1.666667
printf("%lf\n", 10.0 / 6.0);//1.666667
printf("%lf\n", 10.0 / 6);//1.666667
printf("%d\n", x % y);//4
return 0;
}
移位操作符
>> <<
位操作符
& ^ |
赋值操作符
= += -= *= /= &= ^= |= >>= <<=
#include<stdio.h>
int main()
{
int a = 0;
a = 5;//赋值
a = a + 5;//等价 a += 5; - 复合赋值
return 0;
}
单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符
(解引用操作符) (类型) 强制类型转换
#include<stdio.h>
int main()
{
//双目操作符 - 只有一个操作数
//单目操作符 - 只有一个操作数
//在C语言中,非0 - 表示真,0 - 表示假
int a = 5;
if (a)//a为真进入if
printf("X\n");
if (!a)//a为假进入if
printf("x\n");
printf("%d\n", !a);//0
int a = 5;
int b = 0;
b = -a;
printf("%d\n", b);
int a = 0;
//sizeof 操作符,不是函数
//sizeof计算的是变量所占有内存的大小、单位是字节
printf("%d\n", sizeof(a));//4
printf("%d\n", sizeof a);//4
printf("%d\n", sizeof(int));//4
printf("%d\n", sizeof int);//error
int a = 1;
int d = ++a;//前置++ - 先加加后使用
/*
a = a+1;
d = a;
a = 2 , d = 2
*/
int e = a++;//后置++ - 先使用后加加
/*
e = a;
a = a+1;
a = 2 , e = 1
*/
return 0;
}
接下来,我们看一段关于前置++和后置++配合使用的代码,看看输出的结果是什么?
#include<stdio.h>
int main()
{
int a = 1;
int b = (++a) + (++a) + (++a);
printf("%d", b);
}
vs2022测试的结果:
IDEA2020测试的结果
关系操作符
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 4;
int b = 5;
if (a == b)//测试相等
{
printf("1\n");
}
else//a != b - 测试不相等
{
printf("2\n");
}
return 0;
}
> >= < <= != 用于测试“不相等” == 用于测试“相等”
逻辑操作符
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
//并且 && 逻辑与 两个操作数都为真才为真,只要有一个为假就为假
//或者 || 逻辑或 两个操作数都为假才为假,只要有一个为真就为真
int a = 0;
int b = 5;
if (a && b)//假
{
printf("1\n");
}
if (a || b)//真
{
printf("2\n");
}
return 0;
}
&& 逻辑与 || 逻辑或
条件操作符
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
//exp1 ? exp2 : exp3 - 三目操作符
/*
exp1为真,执行exp2,不执行exp3
exp1为假,执行exp3,不执行exp2
*/
int a = 0;
int b = 0;
//输入
scanf("%d %d", &a, &b);
//找到a和b之间的最大值
/*
int m = 0;
if (a > b)
m = a;
else
m = b;
*/
/*不推荐
int m = 0;
(a > b) ? (m = a) : (m = b);
*/
/*三目操作符的使用
int m = 0;
m = a > b ? a : b;
*/
return 0;
}
exp1 ? exp2 : exp3
逗号表达式
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
//逗号表达式
//exp1, exp2, exp3......
//从左向右依次计算,结果是最后一个表达式的结果
int a = 3;
int b = 2;
int c = 5;
int d = (a += 3, b = 5, c = a + b, c - 4);
// a=6 b=5 c=11 c=7
return 0;
}
exp1, exp2, exp3, …expN
下标引用、函数调用和结构成员
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
// 0 1 2 3 4 5 6 7 8 9
//数组下标从0开始
//[]是一个下标引用操作符
printf("%d\n", arr[5]);//6
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Add(int x, int y)
{
return x + y;
}
int main()
{
int z = Add(3, 5);//函数调用操作符
printf("Hello");//函数调用操作符
return 0;
}
[] () . ->
9.操作符的优先级
当操作配合使用时,我们要牢记以下口诀,才能在以后的使用出现不必要的错误
口诀:
单目运算排第一;
乘除余二加减三;
移位四,关系五;
等和不等排第六;
位与、异或和位或;
短路与和短路或;
依次从七到十一;
条件排在第十二;
赋值一定是最后;