“hello world.\n”
由双引号引起来的一串字符被称为字符串字面值,简称字符串
字符串的结束标志是一个\0的转义字符(在字符串中一般不写出来)。在计算字符串长度的时候\0是结束标志 ,不算作字符串的内容。
下面来到编译器中直观感受字符串的特征
1、
#include
int main()
{
char arr1[]="Hello";
char arr2[]={
'H','e','l','l','o'};
char arr3[]={
'H','e','l','l','o','\0'};
char arr4[]="Hello\0";
printf("%s\n",arr1);
printf("%s\n",arr2);
printf("%s\n",arr3);
printf("%s\n",arr4);
return 0;
}
输出结果
由此可见,arr1、arr2、arr4的输出结果是一样的,而arr4的结尾没有加 \0导致其出现乱码。
2、
#include
#include
int main()
{
char arr1[]="Hello";
char arr2[]={
'H','e','l','l','o'};
char arr3[]={
'H','e','l','l','o','\0'};
char arr4[]="Hello\0";
printf("%d\n",strlen(arr1));
printf("%d\n",strlen(arr2));
printf("%d\n",strlen(arr3));
printf("%d\n",strlen(arr4));
return 0;
}
输出结果
由此可见,arr1、arr2、arr4的长度都是一样的,而arr3却不一样(arr3的长度为随机值)。只因为arr3的结尾没有 \0 ,计算机不能准确找到arr3的结尾,因此会出现这个情况。
求字符串长度时使用的strlen需要引用头文件 #include
,与使用printf需要引用头文件 **#include **一样。
转义字符就是转变其原来的意思
- \?
在连续书写多个 ? 时使用,防止被解析为三字母词(也被称为三联符序列,现在已经比较少见了)
- \’
表示字符常量 '
- \"
表示一个字符串内部的双引号
- \
表示一个反斜杠,防止其被解释为一个转义序列符
- \a
表示警告(在计算机读到这个字符会发出蜂鸣声)
- \b
退格符
- \f
进纸符
- \n
换行
- \r
回车
- \t
水平制表符(即键盘上的 “ TAB ”键位)
- \v
垂直制表符
- \ddd
表示一个1~3个八进制的数字。eg:\130 ~ 536(十进制)
- \xdd
dd表示2个十六进制的数字。eg:\x30 0 ~ 48(十进制)
一些转义字符的使用
#include
int main()
{
char ch1='\101';
char ch2 = '\x41';
printf("D:\code\test\2021\4\10\n");
printf("\"D:\code\\test\\2021\\4\\10\"\n");
printf("\v\t\v\t\v\t\v\t\n");
printf("%d\n",ch1);
printf("%d\n",ch2);
printf("%c\n", ch1);
printf("%c\n", ch2);
return 0;
}
输出结果
其中 printf("%c\n", ch1);
输出的是八进制 101 转换成十进制 65后所代表的ASCII码值所代表的符号。
拓展ASCII码表
C语言中有两种注释
一个是 “//” ~ C++风格
一个是 /*…*/ ~ C语言风格
#include
int fun(int x,int y)
{
int z=0;
z=x+y;
return z;
}
int main()
{
int a=0;
int b=0;
scanf("%d%d",&a,&b);
int sum=fun(a,b);
printf("%d\n",sum);
return 0;
}
运行结果
其中 fun 就是我定义的函数
a和b被带入 x,y 的值,并且进行我设计的计算后得到 z,然后通过 return z; 将 z 的值返回到 fun
int arr[10]={1,2,3,4,5,6,7,8,9};
- 数组中的 **[ ]**可以不输入,但是输入的必须是 常量
- 数组中的第一个元素的下标为 0
char arr[]={‘a’,‘b’,‘c’,‘d’,’\0’};
- 字符数组中的单个元素需使用 ‘’ 括起来
=
+=
-=
*=
/=
&=
^=
|=
>>=
<<=
!
逻辑反操作
-
负值
+
正值
&
取地址
sizeof
操作数的类型长度(byte为单位)
~
对一个数的二进制按位取反
- -
前置、后置- -
++
与/- -类似
*
间接访问操作符(解引用操作符)
&&
逻辑与
||
逻辑或
exp 1 ? exp 2 : exp 3
exp 1 , exp 2 ,exp 3 ,…, exp n
[ ]
( )
.
->
>
>=
<
!=
测试“不相等 ”
==
用于测试“相等 ”
auto
每个局部变量都是auto修饰的
break
case
需要搭配switch一起食用
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
static
修饰局部变量
代码1
#include
void test()
{
int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
运行结果
代码2
#include
void test()
{
static int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
运行结果
由代码1和代码2可得
static 修饰局部变量改变了变量的生命周期(本质上是改变了变量的存储类型),让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
存储类型
栈区
局部变量的参数
堆区
动态内存分配的
静态区
全局变量
static修饰的局部变量
修饰全局变量
使全局变量失去了外部链接性,即只能在 本源文件 使用
修饰函数
与修饰全局变量相似
#define定义的是标识符常量
特点:
定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了
宏:
专业术语:
暗示着将小命令或动作转化为一系列指令。.宏的用途在于自动化频繁使用的序列或者是获得一种更强大的抽象能力。
大白话:
某fps游戏插u盘事件
只需简单的操作就可以精准爆头,上天入地无所不能
Ps:“大白话”只是我自己的理解,不一定正确,深入探索没有意义【狗头】
在C语言中,宏都是由 #define 定义的
eg:
#include
#define And(x,y)x+y
int main()
{
printf("%d\n", And(1, 2));
return 0;
}
运行结果
注意!!!
宏只是相当于替换掉了所需要进行的操作,需要和函数区分
eg:
#include
#define And(x,y)x+y
int main()
{
printf("%d\n",3 * And(1, 2));
return 0;
}
运行结果
此时,
3 * And(1, 2) 进行的操作是 3*1+2 = 5