1、简述const的作用,const与#define相比,有何优点
对于C++来说,都是定义常量
不同:
空间:const不占用,#define是替换,不占用
作用时期:const在编译时期使用,#define在预编译时期
作用范围:const的范围取决于在全局还是局部定义,#define的作用范围取决于包含在几个头文件内
类型:const定义时带类型,#define不带类型
优点:const带类型校验
2、头文件中的 #ifndef #define #endif 干什么用?
防止头文件重复包含
3、what's the difference among the data types "char *p","const char *p", "char * const p"and"const char *const p" ?
char* p 内容和方向都可改
const char* p *p不可改 p可变
char* const p p不可变,*p可变
const char * const p 方向内容都不可改
4、局部变量能否和全局变量重名
可以
想调用全局,C里面使用extern C++使用::
int g_val=10;
int main()
{
{
int g_val=100;
{
extern int g_val;
g_val=20;
}
}
}
如果在外面定义一个全局整型变量g_val,想在main中再定义一个,先使用{},int+变量名再次定义
如果想要修改局部的,直接修改即可
想要修改全局的,需要在修改前+{}和extern
5、请简述typedef int(*FUN)(int x, int y)及其作用
PFUN为指向函数的指针类型的新名称,PFUN为int(*) (int,int)的别名
6、C语言中的main函数返回值有什么用?
将程序运行的结果返回给系统
7、VC中有哪些方法避免C编程中的头文件重复包含?
#ifndef #define #endif 通过宏定义的方法只定义一次
#pragma once 只编译依次
8、将程序移植到不同的32位cpu中,经常出现结构字节对齐和大小端的问题,有哪些方法避免?
结构体字节对齐避免方式:程序统一对齐方式,比如按照四个字节对齐,#pragma pack(4)
大小端避免方式:识别大小端是否一致,写判断大小端的函数,如果大小端不一致,写一个转换大小端的函数,进行转换
9、sizeof
struct { short a; long b; char c; }d;
sizeof(d)为什么在不同的平台上得到的值不一样?
不同平台上的数据大小不同
long在32位系统中是4字节,64位系统中是8个字节
10、strcpy()为什么会造成缓冲区溢出?可用哪个函数代替?
strcpy(a,b),如果b的长度大于a能存的空间长度,就会溢出,也就是这个函数没有识别目标缓冲区长度的功能
strcpy_s代替
11、strcat的效率问题,有没有更好的解决方案
如果知道前一个字符串长度,可以直接从尾开始拼接
将前一个字符串长度以参数传入
12、Heap和Stack有什么区别
底层:堆:分配前需要先查链表,寻找是否有空闲的空间,因为有查询的过程,所以慢
栈:在函数内申请空间时,判断是否有空间可分配,如果有,就分配
大小:堆:大
栈:小
生长方向:堆:向高地址扩展
栈:向低地址扩展
效率:堆:慢,因为需要寻找是否有空间空间
栈:快,直接分配
方式:堆:手动
栈:自动
13、请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前操作系统的字节序
大端:平时书写习惯
低字节存高地址
小端:低字节存低地址
unsigned fun()
{
int i=1;
return *(char*)&i==1;
}
14、全局变量和static变量什么区别
区别:
作用域:全局变量:可以被程序中的任何函数访问,在其他文件中都是可见的
静态变量:静态变量分为全局静态变量和局部静态变量
全局静态变量修饰全局,局部静态变量修饰局部
静态变量都只在当前文件可见
初始化:全局变量:整型:自动初始化为0
指针:自动初始化成指针
静态变量:存在于全局区,都只初始化一次,没有初始化默认为0
相同点:
生命周期:全局变量和静态变量都到程序退出时结束
15、二进制数11101101转换为十八进制数是多少?
237/18 (D3)
16、在函数体内声明[1] char *str1 = "abc";和 [2] char str2[] = {'a','b','c'}有什么区别
定义:
指针:str1是变量,存在栈区,指向字符常量区
数组:str2是数组,存在栈区
是否可改:
指针:是指针变量,可以改变
数组:是常量,不可改变
存在区域:
指针:变量,存在栈区,指向字符常量区
数组:数组,存在栈区
占用空间:
数组:5 要包含'\0' strlen(str)不算'\0',结果为4
指针:4 指针大小 strlen(str),结果为4
赋值:
数组:str[0]='x'可以赋值
指针:str[0]='x'不可以赋值,字符常量区,不可改变
一般加const,如const char* str='abcd';
17、strcpy,memcpy,sprintf的区别
目的:
strcpy:字符串复制,也复制结束符'\0'
memcpy:内存块复制,任意类型复制,需要指定复制的字节数
sprintf:格式化字符,根据格式化字符串将多个变量格式化后写入目标字符串
复制的内容:
strcpy:仅复制字符串,也复制空字符'\0'
memcpy:复制指定数量的字节,不管数据类型,不会自动加'\0'
sprintf:根据格式字符串和参数列表,生成并复制格式化后的字符串
返回值:
strcpy:返回指向目标字符串的指针
memcpy:返回指向目标内存的指针
sprintf:返回写入目标字符串的字符(不包含终止的空字符'\0')
安全性:
都不检查目标缓冲区的大小
18、define的使用
(1)使用define定义一年有多少毫秒
(2)使用define定义max函数
(3)define中为何经常会使用 do{ }while(0);来包装多条语句代码
(1)如果定义成#define MS_OF_YEAR (365*24*3600*1000)会发生溢出,结果错误
因此需要定义为#define MS_OF_YEAR (365*24*3600*1000LL) 定义成long long
(2)#define max(a,b) ((a)>(b)?(a):(b)) 要加括号
(3)使用do{ }while(0);可以作为一个整体替换,不会被{}等语句分割,避免被截断
#define M i++;i++;
int i=0;
for(i=0;i<10;)
M
相当于
for(i=0;i<10;)
i++;
i++;
后面的i++在循环外面
使用do{ }while(0);
#define M do{i++;j++} while(0);
for(int i=0;i<10;)
do{i++;j++} while(0);
19、实现一个死循环
while(1);
20、什么是预编译
预处理也叫预编译,在编译之前完成宏定义的替换,以及头文件展开等带#的操作