C++学习之第二天

一、选择题1、在(C、E)情况下适宜采用inline定义内联函数。(多选题)

A、 函数体含有循环语句

B、 函数体含有递归语句

C、 函数代码少、频繁调用

D、 函数代码多、不常调用

E、 需要加快程序执行速度

二、简答题

1.如何判断一段程序是由C 编译程序还是由C++编译程序编译的?

        在编译阶段,C++编译程序会根据函数的类型、参数列表、返回值的不同更改程序中的函数名,这也是C++支持函数重载的原因;而C语言在编译阶段不会对函数名作处理,该是怎样就怎样,因此不支持函数重载。

        Linux下可以通过nm命令列出.c和.cc目标文件的函数和全局函数作为观察

步骤
1.ubuntu终端下将以下add.c 和add.cc文件编译成目标文件文件:  gcc -c add.c 和g++ -c add.cc
2.用nm指令分别查看gcc编译和g++编译下的目标文件的一些函数和全局变量:  nm add.o

结果:1.gcc编译add.c的结果:------>函数名add没发生改变,在编译阶段没经过处理
        0000000000000000 T add
                          U _GLOBAL_OFFSET_TABLE_
        0000000000000014 T main
        
        
    2.g++编译以下add.cc的结果:
    0000000000000030 T main
                      U printf
    0000000000000000 T _Z3addii   //---->C++编译器对add函数名进行了更换,add int int
    0000000000000014 T _Z3addiii  // add int int int 

/*add.c文件*/
#include <stdio.h>
#include <stdlib.h>

int add(int a, int b)
{
    return a+b;
}
int main()
{
    printf("%d\n",add(a,b));
}
/*add.cc */
#include <iostream>
int add(int a, int b)
{
    return a+b;
}
int add(int a, int b, int c)
{
    return a+b+c;
}
int main()
{
    cout<<add(1,2)<<endl;
    cout<<add(1,2,3)<<endl;
}

2.函数重载的原理是什么?

1.函数重载的实现原理:编译器为了实现函数重载,编译器用不同的参数类型来修饰不同的函数名,如void func(),编译器可能会将函数名修饰成_func,当编译器碰到void func(int x)时,编译器可能将函数名修饰为 _func_int. ubuntu下可以用nm查看.o目标文件来查看具体表现。

2.函数重载的条件:1.同一个作用域下  2.函数名相同  3.函数参数个数、类型、顺序不同
注意:函数的返回类型不能作为函数的重载条件。

3.inline函数与带参数的宏定义的区别?

1.宏定义:必须要加括号才能保证运算的完整,即使是加了括号,有些运算仍然有可能与预期不符合,在预处理阶段进行宏展开
2.C++提供内联函数取代宏函数,在编译阶段展开
注意:
    1.在类成员函数内部,函数默认为内联函数。
    2.内联函数在进行声明的时候必须要看到具体实现。
    3.又称为小函数,函数体不要又循环、选择语句,函数体不能过大。

4.vs与Linux内存分配的方式是不是一样的?有什么区别?

Linux的内存分区情况。
1. 栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2. 堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构 中的堆是两回事,分配方式倒是类似于链表。
3. 全局/静态区(static):全局变量和静态变量的存储是放在一块的,在程序编译时分配。
4. 文字常量区:存放常量字符串。
5. 程序代码区:存放函数体(类的成员函数、全局函数)的二进制代码

5.请浅析extern C。

用途:在C++中调用C语言文件。 解析:C++中有函数重载,会对函数名称做修饰,导致调用C语言的函数链接失败,利用extern C可以解决问题。

方法1:常用, C与C++混合编程

#ifdef __cplusplus//C和C++的混合编程
extern "C"
{
#endif
int add(int x, int y)
{
    return x + y;
}
#ifdef __cplusplus
}//end of extern "C"
#endif
/*我的代码理解:
1.__cplusplus为C++的内置宏,在C中不存在
2.上述代码能保证在c++程序中告诉C++程序add函数是要以C语言的方式进行链接,
在C语言里在进行宏展开的时候只会会保留add函数这段代码,其他的不会被执行
#ifdef #endif的用法
*/

方法2,在C++函数声明前加extern "C",告诉编译器 void func()1函数用C语言方式 做链接.

 #include <iostream>
 #include <stdio.h>
 #include <stdlib.h>
 
 extern "C" void func1()
 {
     printf("hello world\n");
 }
 
 int func1(int a,int b)
 {
     return a+b;
 }
 int main()
 {
 
     func1();                                                                                                 
     std::cout << func1(1,2) << std::endl;
     return 0;
 }

通过nm查看目标文件的函数:

1.g++ -c externC.cc

2.nm externC.o

结果:

0000000000000000 T func1     //以C方式链接,因此函数名不变
                 U _GLOBAL_OFFSET_TABLE_
00000000000000b2 t _GLOBAL__sub_I_func1
0000000000000027 T main
                 U puts
0000000000000069 t _Z41__static_initialization_and_destruction_0ii
0000000000000013 T _Z5func1ii //重载一样的函数名发生了改变

三、预习一下类和对象

可以看看预习题

四、编程题(选做,如果觉得自己实现不了,可以先不做,但是一定要坚持跟上)

1、在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

暴力法:算法复杂度:排序算法复杂度 + o(n)
1.先把数组排序好.
2.用两个指针i,j去遍历已排序好的数组,j为i的后继,如果两指针指向的值相同则同时加3,如果不同,i指向的值就是结果。
    -用这个需要考虑指针越界问题----这个数出现在末尾才可能会出现指针越界,把这个特殊情况处理即可

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include<string>
class Mysort
{
public:
	void BubbleSort(int arr[],int len)//冒泡排序
	{
		for (int i = 0; i < len; i++)
		{
			for (int j = 0; j < len - i - 1; j++)
			{
				if (arr[j] >arr[j + 1])
				{
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
	}
	
	int find_1_number(int arr[], int len)
	{
		if (arr[len - 1] != arr[len - 2])//这个数出现在数组末尾的情况,直接返回
		{
			return arr[len - 1];
		}
		int i = 0;
		int j = 1;
		for (; i < len && j < len; i = i + 3, j = j + 3)//两指针指向的值相同,同时移动3位
		{
			if (arr[i] != arr[j])
				return arr[i];
		}
	}
};
int main()
{
	Mysort s1;//实例化对象
	int arr[] = { 33,11,33,11,33,11,88,98,98,88,999,98,88 };//测试数据
	int len = sizeof(arr) / sizeof(int);//
	s1.BubbleSort(arr, len);//冒泡排序
	int ret = s1.find_1_number(arr,len);//结果
	cout << ret << endl;
	system("pause");
	return EXIT_SUCCESS;
}

2、地上有一个m行n列的方格。一个机器人从坐标(0, 0)的格子开始移动,它每一次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格(35, 37),因为3+5+3+7=18。但它不能进入方格(35, 38),因为3+5+3+8=19。请问该机器人能够到达多少个格子?

-待解决

猜你喜欢

转载自blog.csdn.net/weixin_49278191/article/details/121001504