6、函数
函数通常用于将一个特定的功能封装成一个函数,当再次使用该功能时可以直接调用函数而不用再写一遍,从而提高程序的效率,减少代码的重复率。
6.1 函数的定义
函数返回值 函数名(参数列表){
函数语句体;
return 表达式;
}
函数返回值:指的是函数返回一个什么类型的值
函数名:给函数起一个名字,见名知意
参数列表:调用该函数时,需要传递的数据
函数语句体:该函数实现的某一功能的具体实现
return:和函数返回值对应,执行完函数后应返回的值。
注意:函数的定义和实现都在main函数的外面,不可以写在main函数里面!!!
代码示例:
#include<iostream>
using namespace std;
//冒泡排序
//BubbleArray为冒泡排序函数,在主函数中需要是调用
void BubbleArray(int *arr,int length){
for(int i = 0 ; i < length - 1 ; i++){
for(int j = 0;j < length - 1 - i;j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main(){
int arr[6] = {23,21,45,34,12,9};
int length = sizeof(arr)/sizeof(arr[0]);
BubbleArray(arr,length);
cout<<"排序后的数组为:";
for (int i = 0; i < length; i++)
{
cout<<" "<<arr[i];
}
system("pause");
return 0;
}
6.2 函数声明
函数声明的意思是可以先告诉编译器自己有一个函数,然后函数的名字是什么,传递什么参数。而函数的实现主体可以单独定义。
函数声明也是在主函数main的外面,格式如:函数返回值 函数名(参数列表);
6.3 函数调用
函数的调用必须写在main函数里面!!!
直接用: 函数名(参数列表);就可以调用前面申明的函数,代码如函数定义中的代码示例中主函数中调用了BubbleArray(arr,length);
6.4 值传递
函数调用时,将实参的值传递给形参,当形参的值发生变化时不会影响实参,看图理解!!
6.5 函数分文件编写
创建后缀名为.h的头文件 —— 文件中实现函数的声明
创建后缀名为.cpp的源文件 —— 文件中实现函数主体的定义
在主函数中调用函数即可。
7、指针
指针可以用来间接访问内存地址
7.1 指针的定义
类型名 * 变量名;
在代码中举例说明更简单,看代码:
int main(){
int a = 10;//定义一个变量a且赋值为10
int * p;//定义一个指针变量p,int为整形,*为指针,在现在这个p的类型我们可以简单理解为p为内存地址类型
p = &a;//因为p为指针,必须赋值为地址类型,所以这里用了&a
*p = 20;//*p为整数类型,则可以直接赋值为整数
cout<<"p输出后的格式"<<p<<endl;
cout<<"*p输出后的格式"<<*p<<endl;
system("pause");
return 0;
}
运行结果:
指针变量和普通变量的区别:
普通变量放数据,指针变量放地址
可以通过&来获取数据的地址
*变量名的意思是解引用
7.2 指针变量的大小
之前在上篇我们学过用sizeof可以知道一个变量的内存大小,同样我们可以用sizeof知道一个指针的大小。
321上代码:
int main(){
cout<<"字符指针的大小:"<<sizeof(char *)<<endl;
cout<<"整型指针的大小:"<<sizeof(int *)<<endl;
cout<<"长整型指针的大小:"<<sizeof(long *)<<endl;
cout<<"单精度浮点型指针的大小:"<<sizeof(float *)<<endl;
cout<<"双精度指针的大小:"<<sizeof(double *)<<endl;
system("pause");
return 0;
}
123看结果:
可以看出无论是那种类型,只要是指针变量那么内存大小统一占四个字节
7.3 空指针和野指针
空指针:指的是指针变量指向内存编号为0的地址,一般用来初始化指针,并且空指针的内存一般不允许访问。
野指针:通俗来说就是内存指向错误的指针
7.4指针和数组
可以通过指针来访问数组中的空间,通过一个例子来简要说明:
int main(){
int arr[5] = {21,34,45,67,32};
int * p;
p = arr;//将数组的首地址赋值给p,p表示拿到了数据的首地址,那么可以通过*p++便利数组
for(int i = 0;i < 5;i++){
cout<<*p++<<endl;
}
system("pause");
return 0;
}
7.5 指针和函数
指针修饰参数,当形参发生变化时,实参也相应变化,属于地址传递
void swap(int *a , int *b){//交换a,b的值,因为是指针传递,相当于传递了a,b的地址,
//那么这里的a,b主函数中的a,b指向的内存空间相同,则主函数中的a,b的值也在改变
int temp = *a;
*a = *b;
*b = temp;
cout<<"形参中的a:"<<*a<<endl;
cout<<"形参中的b:"<<*b<<endl;
}
int main(){
int a = 10;
int b = 20;
swap(&a,&b);
cout<<"主函数中的a:"<<a<<endl;
cout<<"主函数中的b:"<<b<<endl;
system("pause");
return 0;
}
运行结果:
7.6 const修饰指针
1.const修饰指针:指针的指向可以改变,但是指针指向的值不可以改变
2.const修饰常量,则指针指向的值可以改变,但是指针的指向不可以改变
3.const即修饰指针也修饰常量,则指针的指向不可以改变,指针指向的值也不可以改变
8、结构体
8.1 结构体的概念
结构体属于用户自定义数据类型,即用户根据自己需要的变量类型来定义一个新的变量类型
结构体定义规则:struct 结构体名字 {结构体成员列表};
定义结构体变量有三种不同的方式:
struct 结构体名字 变量名;
struct 结构体名字 {结构体成员列表} 变量名;
struct 结构体名字 变量名 = {成员1,成员2,...};
定义结构体是struct不可以省略,但是定义结构体变量时struct可以省略
8.2 结构体数组
定义规则:结构体名字 数组名[] = {{},{},{},...};
struct Student{
string name;
char sex;
int age;
}stu3;
int main(){
Student arr[3] = {{"张三",'m',20},{"李思",'w',19},{"王五",'m',20}};
system("pause");
return 0;
}
8.3 结构体指针
精华都在代码和注释中了,请仔细阅读
struct Student{
string name;
char sex;
int age;
}stu3;
int main(){
Student stu1 = {"lisi",'w',19};
Student * p = &stu1;//指针指向stu1
p->name = "wangwu";//将名字改为wangwu
p->age = 21;//将年龄改为21
cout<<stu1.age<<endl;//结构体可以用.来访问结构体中的成员变量
cout<<p->sex<<endl;//结构体指针可以用->来访问结构体中的成员变量
system("pause");
return 0;
}
8.4 结构体做参数传递
//结构体定义
struct Student{
string name;
char sex;
int age;
}stu3;
//值传递,子函数中的形参的变化不影响主函数中实参的变化
void printStudent1(Student stu1){
stu1.age = 18;//年龄变为18但不影响主函数中的年龄
cout<<"值传递中stu1的年龄"<<stu1.age<<endl;
}
//地址传递,子函数中的形参的变化影响主函数中实参的变化
void printStudent2(Student * stu1){
stu1->age = 26;//年龄变成了26,则在主函数中的年龄也将变为26
cout<<"地址传递中的stu1的年龄"<<stu1->age<<endl;
}
int main(){
Student stu1 = {"wangwu",'m',21};
printStudent1(stu1);
printStudent2(&stu1);
cout<<"主函数中的stu1的值为:"<<stu1.age<<endl;
system("pause");
return 0;
}
C++的知识点总结就到这里啦,后续会对格式以及更基础的细节进行补充编辑,有些的不对的地方请大家批评指正。