阴间题目
int a[5]={2,4,6, 8,10},*P,**k;
p=a; k=&p;
printf("%d",*(p++)); //输出2 因为使用自增前的值
printf("%d",**k); //输出4,因为p自增了
字符数组
char b[10] = {'h','i'};
b是字符数组因为有默认值\0
C错 D对 因为含有5个字符!!! \0
数组指针和指针数组
指针数组:
int *a[2];
数组指针:
double (*p)[N]; p为一个指向由N个double元素组成的一维数组的指针
但是二者均可以大概当成二级指针使用
为了避免嵌套的条件分支语句if-else的二义性,C语言规定:C程序中的else总是与在其之前未配对的最近的if配对
& 和 *的作用
&:取运算对象的地址
*解引用,取指针变量所指的内容
指针是什么
所谓指针就是存放地址值的变量或常量
或云:指针就是地址
"a"和'a'的区别
"a"是字符串常量
'a'是字符常量
字符数组长度
C语言中基本数据类型有:整型,实型(浮点类型),字符型
关闭文件即是文件指针不再指向该文件
数组名是一个不可变的指针(地址)常量,不可以对其进行加减或赋值计算
C语言中函数由函数首部和函数体组成
负数取模
-13 % 6 = -2 余 -1 规律有目共睹,朝负无穷正无穷的方向!!!
引用数组元素时,下标可以是整型表达式或整型常量
字符数为n个的字符串,占用的内存为n+1,√
continue语句对于while 和 do-while语句来说,意味着跳转去计算while(条件)表达式
if/else后只有一个语句时,可以省略大括号
合法
char a[20];
a = "abc";
不合法,同理其他数组,初始化列表只能存在于声明时
下面这句话就是上面的意思,尽管下面的话很难受
不能在赋值语句中通过赋值运算符=对字符数组/其他数组整体赋值
但是
char *a;
a = "abc";
合法!!!
参数
实参和形参之间是单向传输
形参不可以是表达式,函数调用,只能是变量名或者类型的占位符
实参可以是变量,常量,表达式,函数调用
实参可以为任意类型(这么荒唐竟然认为对,只怪其他错的太离谱)
实参类型一定要在调用时指定 认为这话错
实参类型不需要显式指定,但需要和形参类型兼容或能隐式转换
整体输入输出
不可以对整型浮点型数组进行整体输入输出
可以对字符型数组进行整体输入输出
数组声明
int n;
scanf("%d",&n);
int a[n];
老版本必须编译时确定数组大小,所以这样是错的
后续版本支持在运行时再确定数组大小
卷子里认为这样不合法
取模%只能用于整型,故3.0%2非法
为输入而打开文件时,需要r或r+,注意理解这个输入
函数调用时,形参与实参之间是单向的值传递
宏名与带参数的的括弧之间不应该加空格
数组名和指针变量相互等价×
函数嵌套
函数支持嵌套调用,不支持嵌套定义
跳出循环
break不用用于跳出多层循环
goto可以用于跳出任意层循环
初始化
全局变量和局部静态变量的初始化发生在编译时
运算顺序
阴间题:
a > b ? a : c < d ? c : d
运算顺序为:
(a > b) ? a : (c < d ? c : d)
优先级:! > && >|| > =
x += y -= z += 3;
整个表达式从右向左运算,先算z+=3,再算y -= ...
命名规则
数字字母下划线 数字不开头
三元运算符
(a > b) ? a : b;
条件为真,则值为a
运算符优先级
*= +=这些的优先级一般低于加减乘除取模
所以k *= n%10 先运算%
八进制数十六进制数的输入输出
八进制:%o (%O不可) 字面量: 前面加0 044
十六进制:%x 或 %X 字面量: 前面加0x或0X
二进制数字面量,前面加0b或0B
注释
单行//
多行/* */
字符数组破题
题-1:
题0:
int a;
a='a';
'a'表示ASCII
题1:
char s[] = "apple" :数组长度为6,因为有末尾的\0\
题2:
char c[] = "\t\b\\\0will\n";
strlen(c)的结果是8,\t \b \\ \0(不计入strlen) will \n
scanf使用%s输出时,读到\0即停止
常见转义字符
\'
\"
\t
\b
\n
\0
间接递归调用
12.在函数调用过程中,如果函数A调用了函数 B,函数B又调用了函数A,则
A)称为函数的直接递归调用
B)称为函数的间接递归调用 √
C)称为函数的循环调用
D)C语言中不允许这样的调用
scanf的格式
使用scanf时,必须严格遵照其双引号里的格式进行输入
一般算术运算符优先级高于关系运算符
所以30 - i <= i <=9 其中i为10
先计算30 - i 再从左至右进行两次比较运算
前后缀自增运算符
二者优先级高于加减乘除,表达式中先进行自增,前缀使用自增后的值;后缀使用自增前的值
复杂的:可能导致不可预测的结果,but下面这个例子硬看
int x = 5;
int y = ++x + x++ + ++x;(6+6+8)
又例:
for(i = 1; i++ < 4;);
i=4时, i+= < 4 先自增为5,但使用原来的值4,跳出循环后,i = 5
二维数组作为函数参数
int arr[2][3] int arr[][3] int** ptr
二维数组元素存储
并非按行列格式存放,而是行优先存储(Row-major order),线性存储,按行的顺序进行存储
参数类型转换
形参与实参类型不一致时,实参类型会根据形参类型进行饮食转换
表达式值的存储
表达式的值通常优先存储在寄存器中
逗号表达式
子表达式以逗号分隔,子表达式从左至右运算,整个逗号表达式的值为最后一个子表达式的值
位运算与逻辑运算
& | ^ ~ << >>
&& || !
system
system是<stdlib.h>中的一个函数,参数是字符串
system("cls") 清除控制台
system("pause") 暂停程序,按任意键继续执行
#include
#define
取消宏定义(不在顶部,放在合适位置):
#undef 宏名
条件编译
#ifdef 和 #ifndef
const
格式
%±10.3f :表示宽度为10,小数点后保留3位
+:右对齐; -:左对齐
右对齐在左侧填充space
左对齐在右侧填充space
%e和%E用于以科学计数法输入输出浮点数
+-1.2654e+-5
or
大写E
%o用于输入输出八进制(大写O非法)
%x和%X用于输入输出十六进制
bool的占位符是%d
字符串(char [])的占位符%s
指针的占位符为%p
char 1byte
short int 2byte
int 4byte
long 8 byte
float 4byte
double 8byte
long double 16byte
常用函数
memcpy
memcpy 是 C 标准库中定义在 <string.h> 头文件中的函数,用于在内存中拷贝指定字节数的数据。
函数原型
void *memcpy(void *dest, const void *src, size_t n);
参数说明
1. dest:目标内存的起始地址(数据拷贝到这里)。
2. src:源内存的起始地址(数据从这里复制)。
3. n:需要拷贝的字节数。
返回值
返回目标内存的起始地址 dest。
puts
puts 是 C 标准库中的一个函数,用于将字符串输出到标准输出(通常是终端),并在末尾自动添加一个换行符。它是 <stdio.h> 头文件中的一部分。
---
函数原型
int puts(const char *str);
---
参数说明
str:指向以空字符 \0 结尾的字符串。
---
返回值
成功时:返回一个非负值(通常是输出的字符数,具体依赖于实现)。
失败时:返回 EOF(表示发生错误)(End Of File)
gets
gets 是 C 标准库中用于从标准输入(通常是键盘)读取一行字符串的函数,但由于安全性问题,它在 C11 标准中已被移除,不推荐使用。建议改用更安全的函数,如 fgets。
---
函数原型
char *gets(char *str);
---
参数说明
str:指向一个字符数组的指针,用于存储从输入中读取的字符串。
---
功能描述
与scanf之区别:
scanf以空白字符(space \t \n)分隔输入
从标准输入中读取一行字符串,直到遇到换行符 \n 或文件结束符 EOF。
将换行符替换为字符串结束符 \0。
返回读取到的字符串的指针(str),如果读取失败则返回 NULL。
---
返回值
成功时:返回存储输入字符串的指针(即参数 str)。
失败时:返回 NULL(例如在遇到文件结束符或读取错误时)。
getch
getch() 是 C 语言中用于从键盘接收一个字符的函数,属于非标准函数,一般由 <conio.h> 头文件提供(Windows 下支持,Linux 系统中需用类似功能的库模拟)。
---
功能
直接读取用户输入的字符:不会在屏幕上显示输入的字符。
无缓冲模式:不需要按回车键(Enter)确认输入,直接读取一个字符。
---
函数原型
int getch(void);
getche
getche() 是 C 语言中的一个非标准函数,用于从键盘读取一个字符,同时将输入的字符显示在屏幕上。它与 getch() 类似,但增加了回显功能。
---
功能
从键盘直接获取字符:用户输入的字符会立即返回。
回显输入字符:输入的字符会显示在屏幕上。
无缓冲模式:不需要按回车键(Enter)确认输入。
---
函数原型
int getche(void);
getchar
putchar
输入输出缓存
数组
初始化列表只能存在于定义数组时
二维数组不能只指定行数
可以只指定列数
int arr[][3] = {1,2,3,4,5};亦可 有默认值
二维数组名
二维数组名的类型
理解为指针数组!!!
假设 arr 是一个 int 类型的二维数组,声明为:
int arr[3][4];
arr为二级指针,*(arr+i)可以获得第i行指针
*(*(arr+i)+j)可以获得第i行第j个元素
则:
arr + i 即是 &arr[i] *(arr + i)即是arr[i]
注意:int* ptrarr[4] 这叫指针数组,下面的1叫数组指针
1. arr 的类型是 int (*)[4],即指向包含 4 个整数的一维数组的指针
2. arr[i] 的类型是 int *,指向第 i 行的首元素的地址,正常的一级指针
3. arr[i][j] 的类型是 int,表示具体元素的值。
字符串处理函数
strcmp函数停止比较时机:遇到第一个\0
函数
函数声明又称函数原型
变量
const变量
必须初始化,值不可修改
局部变量(默认修饰符为auto)
函数或代码块内定义的变量,作用域限于函数or代码块内(一对{}内)
生命周期:函数被调用时存储在栈,函数出栈时销毁
生命周期:进入代码块开始,代码块执行结束销毁
不初始化时,值不确定
静态局部变量:以static修饰,生命周期延长为整个程序运行期间
如:静态局部变量保留上一次函数调用结束时的值
register变量:注册变量,请求将变量存储在register中,提高访问速度(只是建议)
全局变量
定义在所有函数之外,作用域为整个程序(通过extern引用,可以在多个文件中使用)
生命周期:程序开始时创建,程序结束时销毁
不初始化时,存在默认值(0,0.0,\0,null)
静态全局变量:以static修饰,作用域局限于声明其之文件,不可用extern引用
普通函数:可以通过extern外部引用
static函数:不可通过extern外部引用
结构体
结构体允许不完全初始化
结构体Example有两个成员:int a float b
struct Example s = {2} 合法!!! b有默认值
共用体
共用体变量data和它的各成员地址相同
枚举类
typedef
指针
多级指针
指针的运算
1.指针的加法和减法
加法 ptr + n: 指针 ptr 加上整数 n,移动指针的位置,指向下一个或后 n 个元素。
减法 ptr - n: 指针 ptr 减去整数 n,指向上一个或前 n 个元素。
注意:指针加减运算的单位是指针指向的数据类型的大小(即 sizeof(type))
3. 指针的减法(指针间的差值)
用法:ptr2 - ptr1 表示 ptr2 和 ptr1 间相隔的元素个数。
要求:ptr1 和 ptr2 必须指向同一数组。
4. 指针的赋值
一个指针变量可以被赋值为另一个指针变量(如果它们的类型兼容)。
使用 void * 类型可以指向任何类型的数据,但需要显式转换以访问具体数据。
示例:
#include <stdio.h>
int main() {
int a = 10;
float b = 20.5;
void *ptr; // 泛型指针
ptr = &a;
printf("Value of a: %d\n", *(int *)ptr); // 强制类型转换为 int*
ptr = &b;
printf("Value of b: %.2f\n", *(float *)ptr); // 强制类型转换为 float*
return 0;
}
返回指针
函数指针
指针与数组
动态内存分配
文件
理解输入输出:
向计算机输入
向文件输出数据
打开文件
建立文件信息区和缓冲区
r:只读
w:只写
a:追加
w+ r+ a+:读写
b:Windows系统中,换行需要\r和\n,而C语言只需要\n即可实现换行
数据在内存中以二进制形式存储,不加转换直接输出至外存,即二进制文件(又称映像文件image file)
在外存中以ASCII码存储,则称文本文件(text file)
文本文件以w打开,向文件输出\n时,转换为\r和\n
文本文件以r打开,从文件读入时遇到\r和\n,将其转换为一个\n
而加上b以为二进制文件打开则无需这种转换
关闭文件
释放信息区和缓冲区
fgetc
每次读取后文件指针后移一位
fputc
每次输出后文件指针后移一位
fgets
成功时,返回get到的字符串,失败时返回NULL
get后指针移动
fputs
put后指针移动
格式化方式读写文本
fseek函数
fseek(FILE* stream,long offset,int origin)
offdet正表示向前移动,负表示向后移动
origin:
SEEK_SET 文件开头
SEEK_CUR 当前位置
SEEK_END 文件结尾
ftell函数
获取当前文件指针位置
long ftell(FILE* stream)
可以将文件指针偏移至最后一位,再调用ftell函数以测量文件大小
rewind函数
文件指针回到文件开头
void rewind(FLIE* stream)