玩命加载中 . . .

C++基础知识-1


变量的声明和定义有什么区别

变量的定义是为变量分配地址和存储空间,变量的声明不分配地址
一个变量可以在多个地方声明,但是只在一个地方定义
加入extern修饰的是变量的声明,说明此变量将在文件以外或在文件后面部分定义。
说明:很多时候一个变量,只是声明不分配内存空间,直到具体使用时才初始化,分配内存空间,如外部变量

int main() {
    extern int A;
    // 这是声明不是定义,声明A是一个外部变量
    // 注意:声明外部变量时可以把变量类型去掉,如:extern A;
}
int A;  // 定义,定义了A为整形的外部变量

简述#ifdef、#else、#endif和#ifndef的作用

利用#ifdef#endif将某程序功能模块包括进去,以向特定用户提供该功能
在不需要时用户可轻易将其屏蔽。

#ifdef __MATH__ 

#include "math.c" 

#endif 

在子程序前加上标记,以便于追踪和调试。
#ifdef DEBUG

printf ("In debugging......!");

#endif

应对硬件的限制。由于一些具体应用环境的硬件不一样,限于条件,本地缺乏这种设备,只能绕过硬件,直接写出预期结果。
注意:虽然不用条件编译命令而直接用if语句也能达到要求,但那样做目标程序长(因为所有语句都编译),运行时间长因为在程序运行时间对if语句进行测试)。
而采用条件编译,可以减少被编译的语句,从而减少目标程序的长度,减少运行时间


写出int/bool/float/指针变量与“零值”比较的if语句

// int与零值比较
if (n == 0)
if (n != 0)

// bool与零值比较 
if (flag)     // 表示flag为真 
if (!flag)    // 表示flag为假 

// float与零值比较 
const float EPSINON = 0.00001;
if ((x >= -EPSINON) && (x <= EPSINON)) //其中EPSINON是允许的误差(即精度) 

// 指针变量与零值比较 
if (p == NULL)
if (p != NULL)

结构体可以直接赋值吗

声明时可以直接初始化,同一结构体的不同对象之间也可以直接赋值,但是当结构体中含有指针成员时一定要小心。
注意:当有多个指针指向同一段内存时,某个指针释放这段内存可能会导致其他指针的非法操作,因此在释放前一定要确保其他指针不再使用这段内存空间


sizeof 和strlen 的区别

  • sizeof是一个操作符,strlen是库函数。
  • sizeof的参数可以是数据的类型,也可以是变量,而strlen只能以结尾为'\0'的字符串作参数。
  • 编译器在编译时就计算出了sizeof的结果,而strlen函数必须在运行时才能计算出来。并且sizeof计算的是数据类型占内存的大小,而strlen计算的是字符串实际的长度。
  • 数组做sizeof的参数不退化,传递给strlen就退化为指针了
int main() {
    char str[6] = "hello";
    cout << sizeof(str) << endl;    // 输出数组大小:6
    cout << strlen(str) << endl;    // 输出字符串长度:5
    return 0;
}

C 语言的关键字 static 和 C++ 的关键字 static 有什么区别

Cstatic用来修饰局部静态变量和外部静态变量、函数。而C++中除了上述功能外,还用来定义类的成员变量和函数,即静态成员和静态成员函数
注意:编程时,static的记忆性和全局性的特点可以让在不同时期调用的函数进行通信,而C++的静态成员则可以在多个对象实例间进行通信

C 语言的 malloc 和 C++ 中的 new 有什么区别

  • newdelete是操作符,可以重载,只能在C++中使用
  • mallocfree是函数,可以覆盖,C/C++中都可以使用
  • new可以调用对象的构造函数,对应的delete调用相应的析构函数
  • malloc仅仅分配内存free仅仅回收内存,并不执行构造和析构函数
  • newdelete返回的是某种数据类型指针,mallocfree返回的是void指针

注意malloc申请的内存空间要用free释放,而new申请的内存空间要用delete释放,不要混用


size_t

size_tcstddef头文件定义的一种与机器实现有关的无符号整数类型,他的空间足够大,能够表示任意数的大小


extern “C”

之所以C++支持函数重载,是因为C++在函数编译阶段对函数名进行再次命名,生成一个函数的签名,这个签名不仅包含函数名,还包含函数的参数列表,所以只要参数列表不同,就可以实现函数的重载

而C语言不支持函数重载,所以函数的签名仅包含函数名信息

假设一个函数display声明在myfun.h头文件中,定义在mufun.c文件中,然后要再main.cpp文件中使用

// myfun.h
void display();

// myfun.c
#include <stdio.h>
#include "myfun.h"
void display() {
    printf("hello");
}

// main.cpp
#include <iostream>
#include "myfun.h"
using namespace std;
int main() {
    display();
    return 0;
}

预处理的时候会将头文件的内容拷贝到myfun.c和main.cpp文件中,编译时,由于myfun.c是用C语言编译的,编译后的函数签名仅跟函数名有关,而main.cpp是用C++编译的,函数签名与函数名和参数列表有关,这样,当调用display时,由于函数签名不同,就找不到display函数的定义了

所以我们应该让display函数在main.cpp中使用C语言的编译方式,只要在myfun.h中使用extern “C”来修饰display就可以了

#ifdef __cplusplus
extern "C" void display();
#else
void display();
#endif

这样在拷贝到main.cpp文件时,会选择extern “C”修饰的display函数,而在拷贝到myfun.c时,会选择不带extern “C”修饰的display函数,保证都可以按C语言的标准来处理


文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录