C语言常见问题
计算
-
变量和表达式
-
'\n' 代表什么: 换行 。
-
'/' 对浮点数和整型的区别是什么:
- case:float,只要操作数中有一个是浮点数,运算结果就为浮点数
- case:int,如果两个操作数都是整数,运算结果如果得到了小数,小数部分会被截断,只保留整数部分。
float: 5/2.0 = 2.5 int: 5/2 = 2
- 取整,取余
- /:取整(向下)
- %:取余
int a = 12258; int b = a / 100; //b = 122 int c = a % 10; //c = 8
-
如果变量不初始化,他的数值是多少?
在linux的C中,如果变量不初始化,它的值是不确定的。因为在变量定义之后,编译时会在堆区给这个变量分配一块内存空间,内存块里面的值是不确定的,可能是随机值,或者之前存储的数据,因此,在使用前最好将定义过的变量初始化。 -
注意:代码风格,提升代码可读性
我采用的:结构上回滚式,变量命名的可读性
google name c++ style -
'0'的ascii码是48,'a' 的是97, 'A' 是65。
-
判断:
- 分支结构
-
++i和i++的区别
++i中i先自加1再参与运算,i++中i先参与外部运算,自己再加一 -
什么是整型变量溢出?
在进行整数运算时,如果结果超出了该类型所能表示的最大范围,就会得到预料之外的结果。主要表现在int,long,short,char上。 -
什么时候用if,什么时候用switch(注意,switch case中,每个case后面别漏了break语句)
- if适用于条件较少,条件之间逻辑上是独立的,或者条件是复杂的布尔表达式,还包含多个逻辑运算符。
- switch case
- 适用于条件较多,
- 条件之间是关联的:他们有共同的判断对象
- switch case最适用于对整型或枚举类型进行判断
- 需要执行不同的代码块,每个case对应不同的代码块,switch可以很好管理这些情况
-
循环
-
循环控制
- 什么时候用while循环,什么时候用for循环?
- 使用while:
- 循环终止条件在每次迭代之前无法确定,导致循环次数不固定。while先判断后执行,do while先执行一次,再判断。
- 使用for
- 循环的迭代次数是已知的时候,如对序列每个元素进行迭代。
-
break和continue分别的作用
- break 跳出本层循环
- continue 跳过本次迭代,忽略continue之后的代码,从下一次迭代开始
数据类型和处理
-
整型有哪些种,它们分别占多少个字节?(64位系统指针变量为8个字节)
-
浮点数和整型之间的转换
浮点数->整型:强转,直接把小数点后面部分截断,取整数部分
整型->浮点型:隐式转换 -
浮点数有哪些类型?分别占用多少字节
-
int a [5]; int* p = a; 所以sizeof(a)和sizeof(p)分别等于多少?
- sizeof(a)是整个数组的大小,p是指针变量,存放地址,本身是8个字节,和指向的对象类型无关。
-
是否了解二进制、八进制、十六进制、十进制之间的互相转换规则?
十进制转任意进制,除以进制数直到商为0为止,每次取余,然后逆向把余数拼接在一起.(56->(70)o)
任意进制转十进制,任意进制数按每一位数的权重和对应幂次依次相加(8进制, (70)o,7*81+0*80 = 56) -
各种类型的整型,他们的大小范围是什么?
- int, long 4个字节:-231~231-1, unsigned 0~2^8-1
- char : 1个字节 signed char: -27~27-1, unsigned char: 0~2^8 - 1
- short int: 2个字节, -215~215-1, unsigned short int 0~2^16-1
函数
- 是否了解条件短路?
短路是指可以让后面的代码不执行
- 什么是函数声明?什么是函数定义?
- 函数定义是指对函数功能的确立,包括函数名,函数返回值,函数体定义,形参类型,排列顺序等,是一个完整的,独立的函数单位。
- 函数声明是把已经定义好的函数基本信息提前告知编译器,以便在调用该函数时系统按此进行对照检查。
-
是否了解递归(递归要多练习题目)
自己调用自己,到终止条件后,从终止点开始回溯到最顶层。(线程栈) -
函数传值和传指针的区别是什么?
无论是传值还是传指针,函数都会生成一个临时变量,但传引用时,不会生成临时变量。 -
一个程序可以有两个main函数吗?
只能有一个,main函数是程序的入口,一个项目只能有main函数。
指针
-
如果p是指针,*p和p分别代表什么
*p解引用,取p所指向的内存的值
p指针变量存储的是地址 -
如果a数组size为6,访问a[6]会发生什么?
越界,size为6的数组,最后一个元素的index是5,因为数组索引是从0开始的 -
二维数组的内存排布
元素的虚拟内存地址都是连续的。
-
字符串和字符数组的区别是什么?
由于C里面没有string关键字,所以不能直接定义字符串,只能用字符数组表示字符串。
- 字符数组:向内存申请的空间大小是数组里存放元素个数*每个元素类型大小
- 字符串:定义了一个字符数组,向内存申请的空间是(数组里存放元素个数+1)*每个元素的类型大小然后,最后一个空位是用来存放只读型字符'\0',用来表示字符串的终止,在编译时自动在字符串的末尾添加此值。 字符串是只读型字符型数组,不能通过指针更改字符串内部数据。
char arr1[] = { 'l','o','v','e' };
char arr2[] = "love";
printf("arr1的内容 :%s\n",arr1);
printf("arr2的长度 :%s\n", arr2);
-
函数参数传入数组会变成什么?
将数组作为实参传入时,实际传入的是数组的首地址,本质上是一个指针。 -
指针常量和常量指针的区别是什么?
- 常量指针(const pointer):指针指向的数据不可改变,但指针本身可以指向其他地址
- 指针常量(pointer to const):指针本身不能改变,但是指针指向的数据可以改变
字符串
- getchat 和scanf的区别:
- getchar()从键盘获取一个字符
- scanf(...)从键盘获取不一样类型的数据,并存到相应的变量中,变量注意要用取地址的方式,坏处是对同一个变量值的输入不能有空格,否则会被认为是两个变量值
- gets(abc)每次只能输入一个字符串
- strlen, strcmp, strcpy, strcat, strchr, strstr
- strlen:统计字符长度,遇到'\0'结束
- strcmp:比较两个字符串的大小,等于0,遇到'\0'结束
- strcpy:char *strcpy(char *dest, const char *src) 把src 所指向的字符串复制到dest
- strcat:将一个字符串(源字符串)追加到另一个字符串(目标字符串)的末尾
- strchr:在一个字符串中查找给定字符第一次出现的位置,并返回该位置的指针,char *strchr(const char *str, int c);
- char *strstr(const char *haystack, const char *needle),在字符串haystack中查找第一次出现needle字符串的位置,如果找到,则返回地址,否则返回NULL。
- malloc出来的变量和局部变量的区别:
- malloc出来的内存块位于一个特别的自由存储区,称为堆区,可以随时开辟,但不用随时释放。
- 局部变量或者全局变量都是系统自动分配管理的,内存位于静态和动态存储区,即栈。
- 全局变量如果不初始化,系统自动初始化为0.
结构类型
- 什么是枚举
- 枚举类型是C语言中的一种基本数据类型,用于定义一组具有离散值的常量,让数据更简洁,更易读。
- 第一个枚举成员的默认值是0,后续成员如无特别指定,依次加一。
- 如何计算结构体占用内存大小
- 第一个成员位于与结构体地址偏移量为0的位置
- 其他成员位于其对齐数的整数倍位置,所谓对齐数就是在编译器默认值和自身字节数大小里取最小值
- 结构体的大小是成员最大对齐数的整数倍。
- 什么是联合体
- 联合体是一个多个成员共享一块内存的数据结构,这些成员的首地址都是一样的
- 此结构的空间由最大size的成员决定。
- 对齐方式要适合其中所有成员
适用于多个成员共享一块内存或者多个成员每次只取其中一个的情况。
程序结构
-
include头文件<>和""区别
- <>是引用标准C库头文件
- ""是工程文件相对路径下的自定义头文件
-
什么是宏?宏和const的区别是什么?(关于C/C++ const)
#define 标识符 字符串- 编译处理方式不同
- define宏是在预处理阶段进行简单的文本替换
- const常量是编译运行阶段使用
- 类型和安全检查不同
- define宏没有类型,不做任何安全检查,只是简单的展开
- const常量有具体的类型,在编译阶段会执行类型检查
- 存储方式不同
- define宏仅仅是展开,有多少次需要就展开多少次,不会分配内存
- const常量会在编译时被分配内存,存储在程序的数据段中
- const的全局不可修改(加载到运算全局区),局部const(加载到栈区)可以通过指针修改
- 编译处理方式不同
-
局部变量、全局变量、静态变量他们的生命周期、作用域是什么?
- 局部变量:
- 栈区
- 随着函数的结束即被销毁,只在作用域可见
- 全局变量
- 从程序运行开始一直存在,一直到程序结束
- 内存分布,分布在静态存储区
- 其他文件要引用,必须使用extern来声明引用的全局变量
- static
- 不管是局部还是全局声明的static变量都放在程序的全局变量区域
- 作用域仅仅局限在它被定义的位置
- 因此全局变量和static变量的区别仅仅是作用域的不同
- 局部变量:
链表
文件
-
什么是重定向
重定向是将默认的输入(键盘)输出(终端)改为其他设备或文件的过程。- 输入重定向:将程序的标准输入从键盘改为读取自文件或其他设备,通常用 < 运算符来执行输入重定向
- 输出重定向:将程序的标准输出从终端改为写入到文件或其他设备,用 > 表示。
-
a和r+模式是什么?