我的C++成长之路(-) 学习阶段 -02 函数、模板、数组的操作

来源:互联网 发布:淘宝直播是不是很赚钱 编辑:程序博客网 时间:2024/06/03 17:13

接着上一节的内容

数组:是若干相同类型的对象集合体,它具有一定的顺序关系,在内存中占有一组联系的内存地址。定义格式:数据类型 数组名[常量表达式];--常量表达式表示数组大小

int a[5];//a有5个元素的整型数组,不能整体输入 cin>>a 或输出 cout<<a

字符数组:用来存放字符量的数组

测试文件Test.cpp,实现2个矩阵的乘法运算

#include <iostream>

using namespace std;

int main(int argc, char* argv[])

{
/*
float x[5], sum = 0;// 输入5个数求平均
cout<<"输入5个数:";
for(int i=0; i<5; i++) cin >> x[i];
for(int i=0; i<5; i++) sum += x[i];
cout<<"平均值:" << sum/5 << endl;*/

//定义一个字符数组并输出其内容
/*
char c[2][5] = {{'c', '+', '+'}, {'H', 'e', 'l', 'l', 'o'}} ;
for(int i=0; i<2; i++)
{
  for(int j=0; j<5; j++) cout<< c[i][j];
  cout<<endl;
}*/


 // 利用字符数组操作字符串
/*

char c[100];
cin >> c;
cout << c;// 控制台输入输出字符
char str[10];
memset(str, 0x00, sizeof(str)-1);// 将数组中所有元素设为空值
memset(&str[9], '\0', 1);// 最后一位设置为0,否则字符串无法定位结束位置
cout << str << endl;// 输出字符串

*/

 /*
int m[3][4]={{1,2,3,4},{2,2,3,1},{5,4,2,3}}; //矩阵1,定义并初始化
int n[4][3]={{6,3,2},{2,8,1},{6,9,5},{2,4,6}}; //矩阵2,定义并初始化
int q[3][3]={{0}, {0}, {0}};// 结果矩阵
for(int i=0; i<3; i++)
  for(int j=0; j<3; j++)
   for(int k=0; k<4; k++)
    q[i][j] += m[i][k] * n[k][j];// 将对应的行和列相应的元素相乘并累加
   for(int i=0; i<3; i++)
   {
    for(int j=0; j<3; j++)
     cout<<q[i][j]<<" ";// 输出结果矩阵
    cout<<endl;//换行
   }
*/

 return 0;
}
函数:C++的模块分为函数(function)和类(class).

本章主要理解函数的概念、使用、参数传递机制、作用域规则、内联函数、函数的嵌套和递归的使用。掌握函数模板的编写方法

定义格式

返回类型 函数名(形参)

{

    ....//语句序列

    return 返回类型的值;

}

函数原型:和变量的使用一样,函数需要先声明后使用,由函数的返回类型、函数名和形参列表组成

语法格式:类型标识符 函数名(形参列表);//注意函数原型是一个语句要以分号结束

形参列表是一组由逗号分隔的参数类型和参数名称组成,在函数声明的时候,参数名可以被省略,但是在函数定义的时候,通常形参必须命名才能使用,形参列表可以为空,但不能省略,在没有任何参数的时候可以用空参数表或关键字void。

函数的调用:除main()函数外,任一函数都不能单独的构成一个完整的程序,任一函数的调用都必须由main()函数直接或间接的去完成,可以使用函数名和一组逗号分隔开的实参来进行调用,调用的结果就是该函数返回值的类型,调用格式:函数名(实参列表)

 函数名中的参数是形参,main函数调用时,传递进来的是实参。函数参数的传递方式:值传递和应用方式传递

大多数下需要给main()函数传递实参,如:dos下 display 1.map命令 1.map就作为实参传递。当无法列举函数所有形参的类型和数目是使用省略号,编译器会暂停类型检测

类型标识符 函数名(...) 或 类型标识符 函数名(形参1,...)  可见只有调用函数时,形参才会被分配内存空间,调用结束后释放

作用域:函数和类之外定义的变量具有全局的作用域,称为全局变量。C++函数体一般包含在{}中即语句块,形参也是局部变量。变量的生命周期从定义时开始,到退出作用域是销毁。局部变量只能在局部作用域中使用,main()函数中的变量也是局部变量,只在主函数中有效,不能被其他函数使用。同样主函数也不可以使用其他函数的局部变量,在相同的作用域中,变量不可以同名。在不同的作用域中,可以使用相同的变量名,它们使用不同的内存。

函数的引入可以实现代码的共享、减少程序的代码量,但是需要时间和空间的开销.

内联函数:可以减少这方面的开销

函数模板:是指建立一个通用的函数,其函数原型和形参类型不具体指定,而用一个虚拟的类型代替。

语法:template <typename T>// T为虚拟的类型名

           template <class T>// template <class T1, typename T2>

写了这么多了,其实我也不想写,但是为了加深理解,而不只是会写代码,就硬着头皮写了,对知识的掌握会有好处的。下面让我们看个例子。

添加一个头文件testFunction.h 编写几个简单的函数

#include <iostream>

using namespace std;
/*pragma once*/
int lcm(int, int);// 声明计算最小公倍数的函数
int gcd(int, int);// 声明计算最大公约数的函数
int countSum(int a, int b);// 声明求和函数

int gcd (int m,int n) //计算最大公约数
{
 if (m > n) swap(m,n);
 while(n > 0)
 {
  int r = m % n;
  m = n;
  n = r;
 }
 return m;
}

int lcm (int m,int n)//计算最小公倍数
{
 return (m*n / gcd(m,n));
}

int countSum(int a, int b)
{
 return a + b;
}

测试文件Test.cpp:

#include <iostream>

using namespace std;

#include "testFunction.h"

inline int sum(int a, int b);// 声明内联函数
template <typename T>// 定义模板

T t_sum(T a, T b)// 返回T类型的函数
{
 return a + b;
}
int main(int argc, char* argv[])
{
 /*
 int m,n;
    cout << "请输入两个非负数: ";
    cin >> m >> n;
    cout << "gcd(" << m << "," << n << ") = " << gcd(m,n) <<endl;
    cout << "lcm(" << m << "," << n << ") = " << lcm(m,n) <<endl;
 cout << countSum(gcd(m, n), lcm(m, n))<<endl;
 */

 /*
 int a = 3, b = 2; 
 cout << "a = " << a << ", b = " << b <<endl;
 cout << "交换后: " << endl; 
 swap(a, b);// 形参的改变不会影响到实参的,如果此次自定义个交换函数是不起作用的
 cout << "a = " << a << ", b = " << b <<endl;
 */
 //cout << sum(2, 3) <<endl;// 内联函数
    int v1=10,v2=20;
 float v3=2.5,v4=4.6;
 cout<<"v1+v2="<<t_sum(v1,v2)<<endl; //调用模板函数,int型参数
 cout<<"v3+v4="<<t_sum(v3,v4)<<endl; //调用模板函数,float型参数
 
 return 0;
}

inline int sum(int a, int b)
{
 return a + b;
}

 案例:控制台输入随机数字作为数字大小,使用指针的方式赋值、并输出

#include <iostream>
#include <time.h>
using namespace std;
int main(int argc, char *argv[])
{
 long nCnt(0);
 cout<<"输入数值个数";
 cin>>nCnt;
 srand((unsigned)time(NULL));// 设置随机产生种子
 int *pnArray = new int[nCnt];
 if(pnArray == NULL) exit(1);
 memset((void *)pnArray, 0x00, sizeof(int)*nCnt);
 for(long loop(0); loop<nCnt; loop++)
 {
  pnArray[loop] = rand();// 系统自动生成随机数
  //cout<<*(pnArray+loop)<<endl;// 输出元素
  cout<<pnArray[loop]<<endl;// 输出元素
 }
 delete [] pnArray;
 pnArray = NULL;
 return 0;
}

案例:

#include <iostream>
#include <time.h>
using namespace std;
// 演示C风格数组的操作
int main(int argc, char *argv [])
{
 long *plArray = NULL;
 plArray = (long *)malloc(sizeof(long)*10);// 开辟动态数组空间
 srand((unsigned)time(NULL));// 设置产生随机随种子
 for(int nCnt(0); nCnt<10; nCnt++)
 {
  plArray[nCnt] = (long)rand();
  cout<<*(plArray + nCnt)<<endl;// 输出随机随元素
 }
 free(plArray);// 释放内存
 plArray = NULL;
 return 0;
}