C语言常见知识点汇总(二)

  1. 动态顺序表中,只有插入操作时需要检查是否需要扩容

  2. .#include<filename.h>,编译器寻找头文件时,会从通过编译选项指定的库目录去找

  3. #include"filename.h",编译器寻找头文件时,会从当前编译的源文件所在的目录去找

  4. 头文件不能定义全局变量,否则如果有多个文件,那链接时会冲突

  5. #define是宏定义指令,#pragma是一个比较复杂的预编译语句

  6. 条件编译指令包括#if、#ifdef,#ifndef,#else,#elif、#endif等,除此之外还有#if defined(xxx)的用法,不过还是建议使用前者

  7. 函数可以递归,宏不能递归,函数参数有类型检查,宏参数无类型检查,宏不存在执行速度,它是查找替换

  8. 由于宏是通过替换完成的,所以操作符的优先级会影响宏的求值,应该尽量使用括号明确优先级

  9. 头文件中 ifndef/define/endif 的作用是防止头文件重复引用

  10. FILETIMEDATE,它们是常用宏,分别用于:打印所在文件、打印编译时间、打印编译日期。除此之外,还有__LINE__(行号)、FUNCTION(函数名)等宏

  11. 程序运行之前需要先载入内存中,载入内存后,便找到main函数,从main函数的开始位置开始执行,程序运行起来后,会为每一次函数调用创建运行时运行时堆栈,程序运行的上下文信息就放在运行堆栈中维护,程序运行结束就停止了,可以通过ctrl+c等方式终止程序

  12. 预处理的作用是将源程序文件进行处理,生成一个中间文件,编译系统将对此中间文件进行编译并生成目标代码

  13. feof函数是在文件读取结束后,判断文件读取结束的原因的,是读取失败结束,还是遇到文件尾结束

  14. feof函数是在文件读取结束的时候,检测是否是因为遇到了文件结束标志EOF,而读取结束

  15. 读取文本判断是否结束时,fgetc看返回值是否为EOF, fgets看返回值是否为NULL

  16. 二进制文件判断读取结束,看实际读取个数是否小于要求读取个数'

  17. test.c文件中包括如下语句:

    cpp 复制代码
    ​#define INT_PTR int*
    typedef int* int_ptr;
    INT_PTR a,b;
    int_ptr c,d;

    文件中定义的四个变量,哪个变量不是指针类型?

    答:#define是查找替换,所以替换过后的语句是"int*a,b;",b只是一个int变量,若令b为指针,必须写成"int *a, *b;"。而typedef没有这个问题,c、d都是指针,故b不是

  18. sprintf是把格式化的数据写到字符串中,与输出流无关

  19. scanf和printf是针对标准输入、输出流的格式化输入、输出语句;fscanf和fprintf是针对所有输入、输出流的格式化输入、输出语句;sscanf是从字符串中读取格式化的数据

  20. 文件名中有一些禁止使用的字符,比如:\/:*?"<>|

  21. 文件的后缀名决定了一个文件的默认打开方式

  22. 文件路径指的是从盘符到该文件所经历的路径中各符号名的集合

  23. 文件名可以不包含后缀名

  24. 文本文件和二进制文件机器都能识别,但是存储的形式有所差异

  25. 文本文件是可以读懂的,二进制文件没办法直接读懂

  26. 数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件

  27. 将内存中的数据转化成ASCII码值的形式,并以ASCII码值的形式存储的文件就是文本文件

  28. getchar只针对标准输入流stdin。即使对stdin重定向,getchar针对的也只是stdin。f系列的输入输出函数都是作用于所有流的的

  29. fgetc是适用于所有输入流字符输入函数

  30. fputs是适用于所有输出流的文本行输出函数

  31. fread是适用于文件输入流的二进制输入函数

  32. fopen打开文件的方式是"r",如果文件不存在,则打开文件失败

  33. fopen打开文件的方式是"w",如果文件不存在,则创建该文件,打开成功

  34. fopen打开的文件需要fclose来关闭

  35. fopen的返回值可以检验文件是否打开成功,打开方式为"r"时尤其重要

  36. free的函数原型为:void free (void* ptr),它的参数可以为NULL

  37. 函数中局部变量的指针不能做返回值

```
如果str字符指针正常则printf("%s",str)正确,printf(str)也正确
```
  1. malloc函数向内存申请一块连续的空间,并返回起始地址

  2. malloc申请空间失败,返回NULL指针

  3. malloc可以向内存申请0字节的空间,malloc(0)是允许的,也会返回一个指针,只是没有空间所以不可使用而已

  4. malloc申请的内存空间,不进行释放会对程序有影响,不释放会产生内存泄漏,小型程序可以不关注,但是在中大型程序上影响极其深刻

  5. 枚举常量与#define定义的常量相比前者的可读性更好,枚举符号提供了有意义的标识符,可以更清晰地表达代码的意图。相比之下,#define定义的符号只是简单的文本替换,不具备语义上的含义。同时前者的常量会有类型检查,更加严谨。

  6. 枚举常量遵循作用域规则,枚举声明在函数内,则它只能在函数内使用,#define定义的符号没有作用域概念,会在整个代码中进行文本替换

  7. 枚举类型在内存中存储为整数

  8. 枚举类型不可以包含浮点数作为枚举值,不可以包含字符串作为枚举值,不可以作为函数的参数传递

  9. 下面代码的结果是?

    cpp 复制代码
    int main()
    {
      unsigned char puc[4];
      struct tagPIM
      {
        unsigned char ucPim1;
        unsigned char ucData0 : 1;
        unsigned char ucData1 : 2;
        unsigned char ucData2 : 3;
      }*pstPimData;
      pstPimData = (struct tagPIM*)puc;
      memset(puc,0,4);
      pstPimData->ucPim1 = 2; 
      pstPimData->ucData0 = 3;
      pstPimData->ucData1 = 4;
      pstPimData->ucData2 = 5;
      printf("%02x %02x %02x %02x\n",puc[0], puc[1], puc[2], puc[3]);
      return 0;
    }

    puc是一个char数组,每个元素单独占用一个字节,而结构体不是,它只有第一个元素单独占一个字节,其他三个元素一起共用一个字节,所以puc被结构体填充后,本身只有两个字节会被写入,后两个字节肯定是0;然后第一个字节是2,puc[0]的打印结果就是02;第二个字节比较麻烦,首先ucData0给了3其实是越界了,1位的数字只能是0或1,所以0011截断后只有1,同理ucData1给的4也是越界的,0100截断后是00,只有5的0101是正常的,填充序列是类似小端的低地址在低位,所以排列顺序是0010 1001,即0x29,最终结果为02 29 00 00

  10. 下面代码的结果为?

    cpp 复制代码
    enum ENUM_A
    {
      X1,
      Y1,
      Z1 = 255,
      A1,
      B1,
    };
    enum ENUM_A enumA = Y1;
    enum ENUM_A enumB = B1;
    printf("%d %d\n", enumA, enumB);

    枚举默认从0开始,所以X1是0,故Y1是1,给了数字后会根据数字向后推,那么Z1是255,A1是256,所以B1是257。

  11. 在X86下以小端字节序存储,下面代码的输出结果为?

    cpp 复制代码
    #include<stdio.h>
    int main()
    {
      union
      {
        short k;
        char i[2];
      }*s, a;
      s = &a;
      s->i[0] = 0x39;
      s->i[1] = 0x38;
      printf("%x\n", a.k);
      return 0;
    }

    union只有2字节,2字节的十六进制只有4位,而位顺序类似小端,低地址在低处,所以39是低地址,在低位,38在高位,所以是3839

  12. realloc函数可以调整动态申请内存的大小,可大可小

  13. malloc函数申请的空间不初始化,calloc函数申请的空间会被初始化为0

  14. realloc在操作过程中是释放旧空间分配并返回新空间,所以返回的新空间也是需要释放的

  15. 下面代码的结果是?

    cpp 复制代码
    #include <stdio.h>
    union Un
    {
    	short s[7];
    	int n;
    };
    int main()
    {
      printf("%d\n", sizeof(union Un));
      return 0;
    }

    结构体向int对齐,7个short一共是14字节,对齐后是16字节。n是单独的4字节,由于是union,所以n与s共用空间,只取最长的元素,故占用16字节

  16. 动态内存分配都是在堆上分配的

  17. 浮点数的存储是按照IEEE754标准,存储了S、M、E相关的值,有的浮点数是不能精确保存的

  18. 整型数据使用固定大小的字节存储,而浮点数数据使用浮点表示法存储

  19. 浮点数的存储和表示方式使用了浮点数表示法,通常是使用IEEE 754标准。这种表示法使用有限的位数来表示一个实数,因此无法精确地表示所有的实数

  20. 结构体类型变量需要访问其成员时,用.运算符,如果是指向结构体变量的指针访问时,需要用->,或者先对指针解引用,取到指向的结构体类型的变量,再通过.访问,但是要注意优先级

  21. 结构体访问成员的操作符包含:. 操作符、-> 操作符、* 解引用操作符

  22. 小端字节序: 低位放在低地址,高位放在高地址;大端字节序:高位放在低地址,低位放在高地址

  23. 大小端字节序指的是数据在电脑上存储的字节顺序而非二进制位顺序

相关推荐
通信仿真实验室24 分钟前
(10)MATLAB莱斯(Rician)衰落信道仿真1
开发语言·matlab
勿语&27 分钟前
Element-UI Plus 暗黑主题切换及自定义主题色
开发语言·javascript·ui
ok!ko3 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
2402_857589364 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰4 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
ChinaDragonDreamer4 小时前
Kotlin:2.0.20 的新特性
android·开发语言·kotlin
IT良4 小时前
c#增删改查 (数据操作的基础)
开发语言·c#
介亭4 小时前
internal.KaptWithoutKotlincTask$KaptExecutionWorkAction 问题 ---Room数据库
jvm
哎呦没5 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
小飞猪Jay5 小时前
C++面试速通宝典——13
jvm·c++·面试