14、指针p与一维数组a的关系(int a[5], *p;p = a;)
地址描述 | 意义 | 数组元素描述 | 意义 |
a、&a[0]、p | a的首地址 | *a、a[0]、*p | a[0]的值 |
a+1、p+1、&a[1] | a[1]的地址 | *(a+1)、*(p+1)、a[1]、*++p | a[1]的值 |
a+i、p+i、 &a[0]+i、&a[i] | a[i]的地址 | *(a+i)、*(p+i)、a[i] | a[i]的值 |
15、指针与数组元素的地址关系(int a[3][4],*p=a[0];(等价于int *p;p =a[0];)):p=a+1是移到下一行的地址,p=a[0]+1,p=&a[0][0]+1,p=p+1是移到下一个元素的地址。
16、指针p与二维数组a的关系(int a[3][4],*p=a[0];)
地址描述 | 意义 | 数组元素描述 | 意义 |
a、*a、a[0]、&a[0][0]、p | a的首地址 | **a、*p 、*a[0]、a[0]][0] | a[0][0]的值 |
*a+1、a[0]+1、 &a[0][0]+1 、p+1 | a[0][1]的地址 | *(*a+1)、*(p+1)、a[0][1]、 *(a[0]+1)、*(&a[0][0]+1) | a[0][1]的值 |
a+1 | a[1][0]的地址 | **(a+1)、*a[1]、a[1][0] | a[1][0]的值 |
a+i | a[i][0]的地址 | **(a+i)、*a[i]、a[i]][0] | a[i][0]的值 |
*a+i*4+j、p+i*4+j、 a[0]+i*4+j、 &a[0][0]+i*4+j、&a[i][j] | a[i][j]的地址 | *(*a+i*4+j)、*(p+i*4+j)、 *(a[0]+i*4+j)、 *(&a[0][0]+i*4+j)、a[i][j] | a[i][j]的值 |
17、常用指针定义形式及含义
int i | i是整型 |
int *i | i是整型指针 |
int **i | i是整型指针的指针 |
int *i[5] | i是含有五个元素的整型指针数组 |
int (*i)[5] | i是指向五个整型元素的指针 |
int *i() | i是返回整型指针的函数 |
int *(*i)() | i是函数指针,函数返回整型指针 |
int *(*i[])() | i是函数指针数组,函数返回整型指针 |
int (*i)() | i是返回整型的函数指针,即i是函数指针,函数返回整型 |
int *((*i)())[5] | i是函数指针,函数返回指向五个整型指针元素的指针 |
18、结构体(struct),联合体(union),枚举(enum)数据类型
19、文件操作FILE *fopen(char *filename,char *type)
下表为:type的取值与所代表含义
type | 含义 | 文件不存在时 | 文件存在时 |
r | 以只读方式打开一个文本文件 | 返回错误标志 | 打开文件 |
w | 以只写方式打开一个文本文件 | 建立新文件 | 打开文件,原文件内容清空 |
a | 以追加方式打开一个文本文件 | 建立新文件 | 打开文件,只能从文件尾向文件追加数据 |
r+ | 以读/写方式打开一个文本文件 | 返回错误标志 | 打开文件 |
w+ | 以读/写方式建立一个新的文本文件 | 建立新文件 | 打开文件,原文件内容清空 |
a+ | 以读/写方式打开一个文本文件 | 建立新文件 | 打开文件,可从文件中读取或往文件中写入数据 |
rb | 以只读方式打开一个二进制文件 | 返回错误标志 | 打开文件 |
wb | 以只写方式打开一个二进制文件 | 建立新文件 | 打开文件,源文件内容清空 |
ab | 以追加方式打开一个二进制文件 | 建立新文件 | 打开文件,从文件尾向文件追加数据 |
rb+ | 以读/写方式打开一个二进制文件 | 返回错误标志 | 打开文件 |
wb+ | 以读/写方式打开一个新的二进制文件 | 建立新文件 | 打开文件,原文件内容清空 |
ab+ | 以读/写方式打开一个二进制文件 | 建立新文件 | 打开文件,可从文件中读取或往文件中写入数据 |
20、文件基本操作
(1)文件操作的错误检测:
1、判断文件流上是否有错int ferror(FILE*stream):若正确,返回值0,若发生错误,返回值非零。
2、判断是否到达文件尾int feof(FILE*stream):若stream所指向的文件到达文件尾,返回值非零,否则,返回值0。
(2)文件的顺序读写:
1、字符读写函数:
<1>从文件读一个字符:int fgetc(FILE*stream)。例如ch =fgetc(fp),即从fp所指的文件中读取一个字符,赋予变量ch,当读到文件尾或读出错时,返回-1(EOF)。
<2>向文件写一个字符:char fputc(charch,FILE *stream)。例如fputc(ch,fp),即把字符变量ch的值写到文件指针fp所值的文件中去,若写入成功,返回值为输出的字符,若出错,返回值为EOF。
2、字符串读写函数:
<1>从文件中读取字符串:char *fgetc(char*string, int n, FILE *stream)。例如fgets(str, n,fp),即从fp所指的文件中读取n-1个字符,放到以str为起始地址的存储空间(str可以是一个字符数组名),若在n-1个字符前,遇到回车换行符或文件结束符,则读操作结束,并在读入的字符串后面加一个‘\0’字符。若读操作成功,返回值为str的地址,若出错,返回值为NULL。
<2>向文件写入字符串:int fputc(char *str,FILE*stream)。例如fputs(str,fp),即将str所表示的字符串内容(不包含字符串最后的‘\0’)输出到fp所指的文件中去,若写入成功,返回一个非负数,否则,返回EOF。
3、格式化读写函数:fscanf和fprintf,具体使用方法略。
(3)文件的随机读写:
1、文件定位函数:int fseek(FILE*stream,long offset,intposition)。例如fseek(fp,d,pos),即把文件指针fp移动到距pos为d个字节的地方。注意pos=0(SEEK_SET)表示文件开始处,pos=1(SEEK_CUR)表示当前文件指针所处位置,pos=2(SEEK_END)表示文件尾。
2、位置函数:long int ftell(FILE*stream)。例如loc =ftell(fp),即将fp所指位置距文件头的偏移量的值赋予长整型变量loc。若正确,loc>=0,若出错,则loc=-1L。
3、重定位函数:void rewind(FILE*stream)。例如rewind(fp),即将文件指针fp重新指向文件的开始处。
另外还有fread和fwrite函数,具体使用方法略。
21、(友情插入)
字符输入函数(上面的一个表),
字符输出函数(下面的一个表)
函数原型 | 函数功能 |
char getc(int ch, FILE *stream) | 从指定的输入流stream中读取字符(stdin表示键盘) |
char getch() | 从键盘读取的字符放入缓冲区,键盘输入的字符不显示在屏幕上 |
char getchar() | 从键盘读取的字符放入缓冲区,键盘输入的字符会显示在屏幕上 |
与scanf输入函数不一样,字符输入函数将空格符、制表符与换行符也作为字符接收。
函数原型 | 函数功能 |
int putc(int ch, FILE *stream) | 将ch所对应的字符输出到stream指定的文件流中 (stdout表示屏幕) |
int putch(int ch) | 将缓冲区中ch所对应的字符输出到屏幕 |
int putchar(int ch) | 将ch所对应的字符输出到屏幕 |
22、位运算
运算符 | 含义 | 运算符 | 含义 |
~ | 按位取反 | & | 按位与 |
<< | 按位左移 | | | 按位或 |
>> | 按位右移 | ^ | 按位异或 |
23、/* */是注释,编译器不管其中的内容。但是编译器会把它替换成空格,所以测试代码“int te/**/st;”编译不会通过。
24、switch语句可以看作跳转,计算控制表达式的值后,程序会跳转到相匹配的case(分支标号)处。分支标号只是说明switch内部位置的路标,在执行完分支中的最后一条语句后,如果后面没有break,就会顺序执行到下面的case里去(直接执行下面case里的语句,而不会再看case的条件),直到遇到一个break,或者switch结束为止。
25、printf中"%-4d'是左对齐占四位。
26、break只能跳出其所在的循环,此时若有多层循环,在最里层break时,若要跳出所有循环,可以使用goto语句来直接跳到最外层,或是设置标志位,跳到上一层循环来判断标志位再继续break。
27、sizeof()是静态处理函数,所以在程序执行前,它就会检查括号内结果的类型,从而给出结果类型的字节数,而运行时即使括号里面的操作是++,也不会执行,所以,对于如下程序段:int a = 6;sizeof(a++);printf("%d",a);a的值仍为6!
28、带小数点的字面量是double而不是float,float需要用f或F后缀来表明身份。
29、对于printf,任何小于int的类型会被转换成int,float会被转换成double,但是scanf不会,要输入short,需要%hd,要输入double,需要%lf。
30、注意const int*和int * const区别,前者是不能通过指针修改所指向的变量,但可以指向别的对象,后者是指针所指向的对象不能改变,但可以改变该对象的内容。
31、注意字符串常量和字符串变量,直接使用指针,对应的是字符串常量,是存储在静态区,不能修改的,要想修改,需要使用数组。
32、注意下面两者间的差别:
33、自增自减运算:
点击打开链接,赋值以及同一个cout语句输出多个表达式都是从右往左的!特别注意(c++) + (++c),先执行++c,得到c的值再代入c++运算!还有(d = f++) + (e = f)先执行d = f++,再执行e = f,再两者相加,注意!在这加号执行完之后f才会执行后置的++!!!
36、注意*的优先级和用法:
前者是返回pointer指向的内容,再将pointer指向的内容自加;后者是返回pointer指向的内容,再将pointer自加,对应下一个地址!
37、数组指针(指向数组的指针):
38、一维数组和二维数组关于指针使用细节上的注意点:
39、返回指针(地址)的注意点: