【C语言】刷了1000道选择题,我总结了初学者常犯错、常会忘记的知识(第一弹)

161 阅读7分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

写在开头:本文结论均有验证,如有错误,感谢反馈!!!

大家好,我是每天都在学习的刻师傅,希望这篇文章对大家有所帮助。 image.png

1.C语言基础知识

1.编译错误、链接错误和运行错误:

image.png

编译错误:一般指语法上的错误(少写;}等等)
链接错误:编译通过,但是无法运行(例如函数只声明,不定义,如图)
运行错误:一般指程序上的bug,使程序出现异常(指针越界等等)

2.进制

C语言中整型常量的表示有三种,八进制(0开头),十进制,和十六进制(0x开头)。
实型数据表示有两种,十进制小数形式和指数形式

3.子串

计算机术语,串中任意个连续的字符组成的子序列称为该串的子串。

4.自定义标识符(取名)

C语言的标识符不能以数字开头(如int 0a=0;)
标识符由字母(A-Z,a-z)、数字(0-9)、下划线“_”组成
并且首字符不能是数字,但可以是字母或者下划线。例如,正确的标识符:abc,a1,prog_to。

1.  不能把[C语言关键字]作为用户标识符,例如if ,for, while等.
2.  标识符长度是由机器上的[编译系统]决定的,标准C声称[标识符]可以任意长。
但是具体还是得看编译器
3.  标识符对大小写敏感,即严格区分大小写。一般对变量名用小写,符号常量命名用大写。
4.  [标识符命名]应做到“见名知意”
C语言中把标识符分为三类:[关键字][预定义标识符][用户自定义标识符] 
C程序的基本组成单位是 【函数】

6.格式化符号%i,%p

1.%i表示有符号十进制整数
它与%d相比较的优点:%i可以自动将输入的八进制或十六进制转换为十进制

2.%p输出地址和%d结果是样的,只不过%p输出是16进制表示

2.语法问题

3.基本数据类型

1.char类型

char a='120' 只会存储最后一个字符,
这属于大小端问题,其次不必研究这种错误代码
再说一点:‘’中最多只能放四个字符

4.操作符

1.do while至少执行一次

2.操作符优先级(重要)

1   ()  []  .  ->                                                             从左至右
2   !  ~   -(负号) ++  --   &(取变量地址)*   (type)(强制类型)    sizeof  从右至左
3   * / %                                                                     从左至右
4   + -                                                                       从左至右
5   >> <<                                                                     从左至右
6   > >= < <=                                                                 从左至右
7   == !=                                                                     从左至右
8   &                                                                         从左至右
9   ^                                                                         从左至右
10  |                                                                         从左至右
11  &&                                                                        从左至右
12  ||                                                                        从左至右
13  ?:                                                                        从右至左
14   =  +=  -=  *=  /=   %=  |=   ^=   &=   >>=   <<=                         从右至左
15  ,                                                                         从左至右

3.if-else

: else只跟离自己最近的if结合

5.关键字

1.const修饰函数

const指定了的函数的返回值表示为常量,不能再当作变量被赋值(也就是不能出现在“=”的左边充当左值)
例如:

image.png

6.构造类型

(1)数组

1.数组和链表

元素个数相同数组内存空间少比链表少(因为链表要保存指向下个节点的指针,占用空间比数组更大)
数组支持随机访问,链表不具有随机访问的特性
插入和删除是链表优于数组,数组需要移动被删除或者插入位置之后的元素

2.柔性数组

结构体中,开辟堆空间时,减少free次数,提高内存利用效率
struct S{
int a;
int arr[0];//大小未知,并且前面至少有一个成员,计算结构体大小时,不考虑这个数组大小。
}
如何使用:malloc时,为其预留你想要的空间大小。
即mallocsizeof(S)+10*sizeof(int));

3.数据的逻辑结构

数据的逻辑结构分为线性结构和非线性结构,线性表是典型的线性结构。
线性表的存储结构有顺序存储和链式存储

4

数组下标越大,遍历数组时间越长。
但是存取都是对单个位置操作的,下标多大在内存里都是地址,拿地址找数据速度都一样。
顺序存取---链式存储;随机存取--数组;索引和散乱---哈希
“随机存取”指的是当存储器中的消息被读取或写入时,所需要的时间与这段信息所在的位置无关,所以叫随机。

因此,查询时,数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);
数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)

(2)结构体

1.同类型的结构体变量可以整体赋值。

	int a;
	struct S* ptr;
}S;

int main()
{
	S s1 = { 10,&s1};
	S s2 ={1000,&s2};
	s1 = s2;
	printf("%d\n", s1.a);//会打印1000
	printf("%p\n", s1.ptr);
	return 0;
}

(3)联合体

(4)枚举

枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。
枚举元素本身由系统定义了一个表示序号的数值,从 0 开始顺序定义
只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。
如一定要把数值赋予枚举变量,则必须用强制类型转换。
还应该说明的是枚举元素不是字符常量也不是字符串常量,使用时不要加单、双引号。
枚举中若某一元素被赋值,则其后的元素值依次在原值上递加1
such:enum weekday
    {sun,mon,tue,wed,thu,fri,sat } a,b,c;
    a=sun;
    b=mon;
    c=tue;

7.指针类型

1.函数指针

通过指针调用函数的两种形式:
1、ret = (*p)();
2、ret = p();//可以发现*可有可无,但是如果加*,就必须带括号

对函数指针赋值的两种形式:
1、pf = &func;
2、pf = func;//&这个操作和数组不同,不存在首元素之分
NULL 和 0 或 '\0' 打印的值,但类型,意义都不同,注意区分。
如图,可以注意到下面有类型不匹配的警告
注:NULL为一个宏 (void*)

image.png

8.函数

1.scanf函数:所有的“非输入控制符”都要原样输入。

1.scanf("a=%d", &a);//输入时,这里的a=也需要输入

2.scanf中的格式控制符不能指明浮点数的精度,即scanf("%.2lf",a);不可以!!!如图

3.* 是scanf函数中的一种修饰符,表示忽略该输入项,使用方法为:放在%与格式d(或者s,c等)之间

image.png 2.输入输出:

fgetc函数——读取成功,带回所读的字符,失败返回文件结束标志EOF(-1);
fputc函数——输出成果,返回值就是输出的字符,失败返回EOF;
fgets函数——读取成功,返回地址str,失败返回NULLfputs函数——输出成果,返回0,失败返回非0

3.printf函数

printf("%d,%d",a,b,c);
//输出项个数少于格式描述符的个数呢,会输出不定值
printf("k=%%d\n",k);   
// %是控制符,用 %% 表示输出一个百分号,%%d相当于字符转义字符%和d

9.文件

1.文件后缀

exe文件可直接运行,.obj文件不能运行。
因为.exe属于可执行文件,.obj文件只是源代码生成可执行文件的过程中生成的过程文件。
在计算机DOS下,生成一个可执行文件,需要用编译器将源程序编译为obj文件,再用链接器将obj文件链接成exe文件。
只有可执行文件才能直接运行。可执行文件还包括.sys文件 .com等类型文件。

10.预处理

1.宏定义

首先宏不仅仅可以写成函数,也可以定义符号常量;
其次宏替换不是在编译阶段,而是在预编译阶段;
最后,性能的影响是有的,但不能绝对的说是好的影响还是坏的影响,
这要看宏定义的好坏了,定义好了可以提高性能,定义不好就会拉低性能