初步C语言

初步C语言,第1张

运算符
  1. 运算符的优先级要熟悉

  • 运算符描述实例
    sizeof()返回变量的大小。sizeof(a) 将返回 4,其中 a 是整数。
    &返回变量的地址。&a; 将给出变量的实际地址。
    *指向一个变量。*a; 将指向一个变量。
    ? :条件表达式如果条件为真 ? 则值为 X : 否则值为 Y
  • a++=b++;是不可以的

    赋值运算符的左边只能是变量,a++是表达式。

  • ++a=++b;是可以的

    前缀++可以,这就是C++的设定,C不行。

a=5,b=10;
a=b++;
printf("%d,%d", a, b);
//结果是10,11
  • a++的具体运算过程为

int temp=a; 
a=a+1;
return temp;
  • ++a的具体运算过程为

a=a+1;
return a;
  • 后置自增运算符需要把原来变量的值复制到一个临时的存储空间,等运算结束后才会返回这个临时变量的值。所以前置自增运算符效率比后置高。

输入输出
  1. scanfgets的区别?

    gets():从标准输入(stdin)中读取字符串,直到到达换行符或文件末尾。

    • scanf在C语言中能对各种类型进行输入,gets用于对字符串的输入。

    • gets可以接收空格;而scanf遇到空格、回车和Tab键都会认为输入结束。

  2. getch

    从键盘读取单个字符。但它不使用任何缓冲区,因此立即返回输入的字符,而无需等待 Enter 键。

  3. getche*

    从键盘上读取单个字符,并立即显示在输出屏幕上,而无需等待回车键。

预处理

C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CPP。

  1. 程序的编译过程分几个部分?

    编译器将 C 程序转换为可执行文件。C 程序成为可执行文件有四个阶段:

    1. 预处理

      这是传递源代码的第一阶段。此阶段包括:

      • 删除注释

      • 宏的扩展

      • 包含的文件的扩展。

      • 条件编译

      预处理的输出存储在文件名.i中。

    2. 汇编

      快照显示它是汇编语言,汇编程序可以理解。

    3. 集会

      此阶段,只有现有代码被转换为机器语言,像printf()这样的函数调用不会被解析。

    4. 连接

      在这个阶段中,函数调用与其定义的所有链接都已完成。链接器知道所有这些函数的实现位置。

关键字 C存储类(static,auto,register,extern)

存储类用于描述变量/函数的功能。这些功能基本上包括范围,可见性和寿命,这有助于我们在程序运行时跟踪特定变量的存在。

static*
  1. 关键字 static 的作用是什么?

    声明静态变量(保留其值的属性,即使它们超出了其范围!)

    • 当static 修饰局部变量时,可以在函数调用之间保持局部变量的值。

      static int a = 0;
  • 当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。

auto
  1. 关键字auto的作用是什么?

    auto 存储类是所有局部变量默认的存储类。因此,在用C语言编写程序时很少使用关键字auto。 auto int month;

register
  1. 关键字register的作用是什么?

    用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个字),且不能对它应用一元的 '&' 运算符(因为它没有内存位置)。 register int miles;

  2. 使用时需要注意什么?

    寄存器只用于需要快速访问的变量,比如计数器。还应注意的是,定义 register并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中,这取决于硬件和实现的限制。

extern
  1. 关键字extern的作用是什么?

    extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。当您使用 extern 时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置。

  2. extern"C"的作用是什么?

  3. C语言编译过程中,关键字volatile和extern分别在哪个阶段起作用?

const*

关键字const用来定义常量(如果一个变量被const修饰,那么它的值就不能再被改变)。

  1. const常量和#define的区别是什么?

    • 预编译指令只是对值进行简单的替换,不能进行类型检查

    • 可以保护被修饰的东西,防止意外修改,增强程序的健壮性

    • 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的 *** 作,使得它的效率也很高

volatile*
  1. 关键字 volatile 的作用是什么?

    volatile修饰的变量表明是随时改变的,程序执行时不要进行编译优化,既每次都从变量的地址中读取数据。

sizeof
  1. sizeof关键字的作用是什么?

    计算数据类型或变量长度(即所占字节数)

  2. sizeof和strlen的区别是什么?

    1. 类型:Sizeof 运算符是一元运算符,而 strlen() 是 C 中的预定义函数

    2. 支持的数据类型: Sizeof 给出以字节为单位的任何类型的数据(已分配)的实际大小(包括空值),而获取字符/字符串数组的长度。

    3. 计算大小:sizeof() 是一个编译时表达式,为您提供类型或变量类型的大小。它不关心变量的值。 另一方面,Strlen 为您提供了 C 样式 NULL 终止字符串的长度。

    4. 总结: 这两者几乎是不同的概念,用于不同的目的。

typedef

为数据类型指定新名称。

#include 
//此行之后可以使用 BYTE代替unsigned char
typedef unsigned char BYTE;
  
int main()
{
    BYTE b1, b2;
    b1 = 'c';
    printf("%c ", b1);
    return 0;
}

C 中的 #define 是用于各种数据类型定义别名的指令。

#include 
//在这条线之后 HYD 被替换为“Hyderabad”
#define HYD "Hyderabad"
  
int main()
{
    printf("%s ", HYD);
    return 0;
}
  1. 以下两种情况的意图都是要定义 dPS 和 tPS 作为一个指向结构体 s 的指针。哪种方法更好呢?为什么?

#define dPS struct s * 
typedef struct s * tPS;
  1. typedef和#define有什么区别?

    1. typedef仅限于为类型提供符号名称,而#define也可用于定义值的别名,例如,您可以将1定义为ONE,3.14定义为PI等。

    2. typedef 解释由编译器执行,其中#define语句由预处理器执行。

    3. #define不应以分号结尾,但 typedef 应以分号结尾。

指针

指针存储变量地址或内存位置。

type *var_name;  //声明指针变量
  • &:返回变量地址

  • *:声明指针变量、访问存储在地址中的值

  1. 什么是指针数组?

    可以定义用来存储指针的数组

    int *ptr[MAX];
  2. 什么是函数指针?

    指向函数的指针变量。通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。

    typedef int (*fun_ptr)(int,int); // 声明一个指向同样参数、返回值的函数指针类型
    /* p 是函数指针 */
    int (* p)(int, int) = & max; // &可以省略
  3. 函数指针有什么作用?

    函数指针可以像一般函数一样,用于调用函数、传递参数。

  4. 引用与指针的区别?

    指针和引用都是地址的概念;指针指向一块内存,它的内容是所指内存的地址;而引用则是指向某块内存的别名。

    • 引用访问一个变量是直接访问的,指针是间接访问。

    • 指针是一个实体有自己的内存,而引用仅是个别名,本身不单独分配自己的内存空间

    • 指针可以为空;引用不能为空,引用在开始时就绑定了一个内存空间,在定义时必须初始化,所以它只能是这个内存空间的名字,之后不可变,内存空间的值是可变的;

  • 局部变量在堆中创建,函数返回后局部变量会被释放,所以不能返回局部变量的地址,局部变量在释放后会丢失(特别经典)

函数
return_type function_name( parameter list 参数)
{
   body of the function
}
  • C中:如果函数未指定返回值类型,则默认为int

字符串*
  1. strcmp函数

    strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1s2 则返回大于 0。

  2. strstr函数

    strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

  3. strcpy函数 *

    strcpy()是 C/C++ 中的标准库函数,用于将一个字符串复制到另一个字符串。

  4. strlen()

    计算给定字符串的长度。它不计算空字符“\0”。

结构体、联合体

C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。

struct Books //结构体标签
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book; //结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量。
  book = {"C 语言", "RUNOOB", "编程语言", 123456}; //对结构体变量可以在定义时指定初始值

联合体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的联合体,但是任何时候只能有一个成员带有值

union Data
{
   int i;
   float f;
   char  str[20];
} data;
  • 16位机器下不考虑字节对齐

其他*
  1. 不定义新的变量,怎么直接交换两个变量的值?(加减方法和异或方法)

  2. 装箱

    把值类型转换为引用类型。

  3. 拆箱

    把引用类型转换为值类型。

  4. classstruct区别

    class作为对象的实现体,它默认的成员变量访问控制是private的。引用类型—分布在堆上。

    struct作为数据结构的实现体,它默认的数据访问控制是public的;值类型—分布在栈上。

  5. 函数参数*

    如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

    当调用函数时,有两种向函数传递参数的方式:

    • 传值调用:该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。

    • 引用调用:通过指针传递方式,形参为指向实参地址的指针,当对形参的指向 *** 作时,就相当于对实参本身进行的 *** 作。

  6. 局变量与局部变量在内存中的区别*

    • 全局变量保存在内存的全局存储区中,占用静态的存储单元;

    • 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。

  • x=x&(x-1),用于计算x的二进制中1的个数,也可以判断一个数是不是2的n次方

  • 初始化指针时所创建的字符串常量被定义为只读,如果试图修改这个字符串的值,程序就会出现未定义的行为

  • 数组作为函数的参数时会退化成指针

函数重载

函数重载是一种编程语言的特性,它允许一个人拥有许多具有相同名称但具有不同签名的函数。

但C不支持这个特性,因为编译器不支持它(除非你可以使用_Generic)。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/789166.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存