0%

带你学c带你飞day02

P11

1
2
3
4
5
6
scanf("%d", &i);//地址
if(i>0)
printf("true");//这样缩进可以
if(){}
else if(){}
else{}

P12

1
2
3
4
5
6
7
switch(表达式){
case 常量表达式1:语句或代码块;
case ...
.
.
default: 语句或代码块;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main(){
char ch;
scanf("%c",&ch);
switch(ch){
case 'A': printf("hi");
break;
case 'B': printf("hey");
break;
default: printf("hello");
break;//不加break会导致所有case都输出了
}
}
1
if(has = "a"){}//永远对,所以应该 ==

P13

1
int getchar();//读取下一个字符
1
2
3
4
while(){}//判断后循环
do{

}while();//先循环在判断,while后面有语句

P14

1
2
3
4
for(循环初始;循环结束;循环条件){}
_Bool flag = 1;
for(int i=0, int j=0;i<j;i++,j++){}//也可以
若想 int i=0, j=10;//则需 gcc -std=c99 test.c && ./a.out

P15

1
2
long longprintf中是%lld
break跳出当前循环,continue直接进入下一次循环

P16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int i=5, j;
j=++i;//i=6=j
i=5;
j=i++;//i=6,j=5
//i++先把值给j,再加加
//多语句,逗号表达式
/* 语法:表达式1,...表达式n
表达式从左到右计算
逗号表达式作为一个整体,值为最后一个表达式也就是n的值
*/
a=(b=3, (c=b+4) +5)//a=12
exp1 ? exp2:exp3 //if exp1==true , exp2, else: exp3
//goto 跳到标签
goto A;//谨慎用goto
A: printf("a");

P17

1
2
3
4
5
6
7
//数组 类型 数组名[元素个数]
/*数组不能动态定义
int 自动初始化为0,最好手动初始化,要不然栈内空间会错误赋值,可能。
int a[5]={[2]=2,[3]=3};//这样可以
sizeof(a);//计算数组内存大小

*/

P18

1
2
3
//动态数组
c99, c支持可变长数组,数组长度在运行时才被决定
新编译, 在数组越界不会出现错误,好像

P19

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
字符串数组定义:
char s[3]={'a','b','\0'};
char s[]={'a','b','\0'};
char s[]={"ab"};
char s[]="ab";
字符串处理函数:<string.h>内
strcat:连接字符串
strcmp:比较字符串
strcpy:拷贝字符串
strlen:获取长度
strncat(str1,str2,5):(以下3个受限,功能一样)//str2拷贝5个字符到str1
strcmp:
strncpy:
sizeof(str);//n
strlen(str);//n-1, 因为strlen不包括那个\n,sizeof包括

1 字符串基础

字符串是一种重要的数据类型,有零个或多个字符组成的有限串行。

定义子串: 串中任意个连续的字符组成的子序列,并规定空串是任意串的子串,任意串也是其自身的子串,如字符串”adereegfb”中它本身、空串、诸如”ader”连续的字符串都是它的子串。子序列则不要求字符连续,但顺序要与主串保持一致,若有”abcd”与”ad”则两者的最长公共子序列为”ad”。在动态规划中计算最长公共子序列和最长公共子串中一定要能区分这两个概念!

在C语言中并没有显示的字符串类型,它有如下两种风格的字符串:

  • 字符串常量: 以双引号扩起来的字符序列,规定所有的字符串常量都由编译器自动在末尾添加一个空字符
  • 字符数组: 末尾添加了’\0’的字符数组,一般需要显示在末尾添加空字符。
1
2
3
char c1[]={'c','+','+'}; //末尾没有空字符
char c2[]={'c','+','+','\0'}; //末尾显示添加空字符
char c3="c++"; //末尾自动添加空字符

注意到通过字符数组初始化和字符串常量初始化并不完全相同的。因为字符串常量包含一个额外的空字符用于结束字符串,用它来初始化创建数组时,末尾会自动添加空字符。所以c1的长度是3,后两者的长度是4,并且字符数组c2和c3都被称为C风格字符串,而字符数组c1不是C风格字符串。

规定C风格的字符串都是以NULL空字符(‘\0’)作为终结符结尾。由于它是字符串的终止符,但它本身并不是字符串的一部分,所以字符串的长度并不包括NULL字节,如strlen函数。而且C标准库中提供的各种字符串处理函数都要求提供的字符串或字符数组必须以空字符结束,否则会出现不可预料的结果。如:

1
2
char c[]={'c','+','+'};
printf("%d\n",strlen(c)); //结果输出为6,这是不正确的

2 标准库中的字符串处理函数

C标准库中头文件定义了两组字符串函数(C++中用表示)。

  • 第一组函数的名字以str开头,它主要处理以’\0’结尾的字符串,所以字符串内部不能包含任何’\0’字符。
  • 第二组函数的名字以mem开头,主要考虑非字符串内部含有零值的情形,它能够处理任意的字节序列,操作与字符串函数类似
  • 除了memmove函数外,其他函数都没定义重叠对象间的行为

为了提高程序在不同机器上的移植性,利用typedef定义新类型名,即typedef unsigned int size_t。 程序员必须要保证目标字符数组的空间能够足以存放结果字符串(有可能存在字符数组溢出的危险)

  • 字符串处理类

如下表为字符串处理函数说明,变量s,t的类型是char *, cs和ct的类型是const char *;n的类型为size_t,c的类型为int

img

  • 内存操作类

按照字节数组的方式操作对象,提供一个高效的函数接口(提供字节流的访问)。其中s,t类型是void * , cs,ct的类型是const void *; n类型为size_t,c类型为int

img

总结起来,头文件< string.h>实现了如下函数:

  • 长度计算、长度不受限和受限的复制、连接和比较版本的函数
  • 基础字符串查找(查找一个字符、一组字符和匹配一个子串)、高级字符串查找(查找子串前缀位置、返回token标记)
  • 处理任意字节序列的内存操作如复制、比较、查找和初始化等函数

P20

1
2
//二维数组矩阵
和一维数组一样