C面试宝典——概念题

来源:互联网 发布:常见数据库设计 编辑:程序博客网 时间:2024/06/04 19:38

1.内存

  • RAM

    • 数据段
    • 栈区(stack)——自动分配,释放,类似栈 (局部变量
    • 堆区(heap)——程序员分配,释放,类似链表
    • 全局区(静态区static)——存放全局变量和静态变量,系统释放
    • 文字常量区(const修饰)——存放常量和字符串存储,自动释放

    -代码段

    • 程序代码区——存放函数体二进制代码
  • ROM

全局变量

特性 全局变量 两个全局变量可否重名 可以,局部会屏蔽全局变量 如何引用一个定义过的全局变量 头文件引用(变量有错误会在编译期间报错); extern关键字(变量有错误会在了解期间报错) 可不可以被定义在多个.c文件的头文件中 可以,在不同.c文件中static修饰,但是只能一个赋值 静态全局变量和非静态全局变量(有无static修饰) 静态全局变量作用域是整个源程序,非静态全局变量作用域是单个源文件

static

特性 static 普通 函数(作用域不同) 内存只有一份 每个被调用维持一份拷贝 全局变量 只初始化一次,防止其他文件单元中被引用 可多次初始化 局部变量 只被初始化一次,下一次依据上一次结果值
    //main.cpp      int a = 0; //全局初始化区    char *p1; //全局未初始化区    main()    {        int b;//栈        char s[] = "abc";//栈        char *p2; //栈        char *p3 = "123456"; //123456\0在常量区上,p3在栈上        static int c =0;//全局(静态)初始化区        p1 = (char*)malloc(10); //堆区        strcpy(p1,"123456");//123456\0在常量区,编译器可能将p3和这个优化为一处    }

堆和栈

区别 堆 栈 申请方式 自动分配 程序员申请 全申请后系统响应 只要栈剩余空间大于所申请空间,就提供,否则提示栈溢出 类似链表 申请大小的限制 堆是向高地址扩展的数据结构,是不连续区域,所以比较灵活,空间较大 栈是向低位扩展的数据结构,获得的空间较少,连续的内存 申请效率的比较 速度快 速度慢,会有内存碎片,但是灵活 申堆和栈的存储内容 固定方式 不固定存储 存储效率的比较 运行时赋值,存取快 编译时确定

const(只读,常量区)
优点:1.清晰方便
2.保护那些不希望被修改的参数
const int a;//a是一个常整型数
int const a;//同上
const int *a;//指向常整型数的指针(const int )
int *const a;//指向整型数的常指针( *const)
int const a const;//指向常整型数的常指针(const 和 a const)


2.static作用

  • 在函数体内,一个被声明为静态的变量在被调用过程维持其值不变
  • 在模块内,一个被声明为静态的变量可以被模块内所有函数访问,但不能被模块外其他函数访问,是一个全局变量
  • 在模块内,一个被声明为静态的函数只能被模块内其他函数调用(本地化)

3.引用和指针的区别

引用 指针 要初始化 可以不必初始化 引用初始化后不能被改变 可以指向其他对象 不存在指向空值的引用 可以指向空值 可读性强,但不方便 可读性差,但方便

4.小知识

#include<file.h>和#include "file.h"//区别:前者直接从标准路径(standard library)寻找头文件;后者从当前工作目录搜寻#(预编译,实现代码文本替换工作,可以放在程序任意位置)1.宏定义  2.文件包含  3.条件编译.h头文件中的ifndef/define/endif的作用//防止头文件被重复引用实时系统的特性//在特定时间内完成特定的任务,具有实时性和可靠性什么是平衡二叉树//左右子树都是平衡二叉树,左右子树深度差值的绝对值不超过1堆栈溢出的原因//1.没有及时回收垃圾资源;2.层次太深的递归调用冒泡排序算法的时间复杂度//O(n^2)什么函数不能是虚函数//constructor(静态成员函数)、构造函数和内联函数(C++)队列和栈的区别//先进先出和先进后出不能做switch()的参数//实型(如:float)while(1)//和for(;1;)相同,和for(;;)相同,和loop:--- goto loop;相同三种数据模型//层次,网状,关系模型关键字 volatile//定义为volatile的变量是说这个变量可能意想不到的变化,这样, 编译器就不会去假设这个变量的值 //三个volatile(1.并行设备的硬件寄存器 2.中断子查询会访问到的非自动变量 3.多线程应用中被几个任务共享的变量)//一个参数既可以是const也可以是volatile,假如这是一个寄存器,因为它可能意想不到变化,所以提箱程序员不应去改变它//一个指针可以使volatile,假如这是个中断子程序,子程序指向一个指针结构和联合的异同//相同点:都是由多个不同数据类型成员构成不同点:联合共用一块地址,对不同成员赋值,其他成员也会重写,原来成员值不存在了;结构不同成员存放地址不同,赋值不影响const 和#define相比//const(定义常量,修饰函数参数,修饰函数返回值,可以提高健壮性)//区别:const有数据类型,define没有;const有类型检查,define只有字符替换,没有类型检查;const可以调试,define不能数组和指针的区别//内存:数组在静态存储区或栈上创建;指针可以使任意内存块//修改内容:char a[] = "hello";a[0] = 'x';char *p = "world";p[0] = 'x';//错误//sizeof:sizeof(a)-->测出数组a长度;sizeof(p)-->测出一个指针变量长度BOOL,int,float,指针类型的变量a与0的比较语句BOOL: if(!a)or if(a)int : if(a == 0)float:const EXPRESSION EXP = 0.000001        if(a < EXP && a > -EXP)pointer:if(a != NULL)or if(a == NULL)判断程序是c还是c++编译的#ifdef_cpluspluscout << "c++";#elsecout << "c";#endif宏和函数带参宏编译时处理,不占用运行时间,函数在程序运行时,调用和返回占用时间;带参宏没有数据类型,函数有带参宏不分配内存,函数分配内存带参宏使程序长度变长,函数不变带参宏不占用  两个栈实现一个队列//设A,B两个栈,一开始为空1.新元素push入栈A2.栈A所有元素pop出push到B3.B的栈顶元素pop出位操作//给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a的bit3,要保持其他位不变#define BIT3(0x1 << 3)static int a;void set_bit3(void){    a |= BIT3;}void clear_bit3(void){    a &= ~BIT3;}访问某特定的内存位置假如要求设置一个绝对地址0x67a9的整形变量的值为0xaa66int *ptr;ptr =(int *)0x67a9;*pte = 0xaa66;中断子程序(不return,不传递参数,不用printf)Typedef#define dPS struct s*typedef struct *s *tPS;dPS p1; dPS P2;//分开声明tPS p3,p4;//可以一起声明一个整型数 // int a;一个纸箱整型数的指针 // int *a;一个指向指针的指针,它纸箱的指针是指向一个整型数 // (int *)*a;一个有10个整型数的数组 // int a[10];一个有10个指针的数组,该指针是指向一个整型数的 // int *a[10];一个指向有10个整型数数组的指针 // int (*a)[10];一个指向函数的指针,该函数有一个整型参数并返回一个整型数 // int (*a)int;一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整形数 // int (*a[10])int;
0 0
原创粉丝点击