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. 大小端字节序指的是数据在电脑上存储的字节顺序而非二进制位顺序

相关推荐
一只爱打拳的程序猿10 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
杨荧11 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck13 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
白子寰18 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
王俊山IT30 分钟前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。32 分钟前
c++多线程
java·开发语言
小政爱学习!34 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
daqinzl40 分钟前
java获取机器ip、mac
java·mac·ip
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
激流丶1 小时前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic