当前位置: 首页 > wzjs >正文

做云教育集群网站网络推广公司哪里好

做云教育集群网站,网络推广公司哪里好,比较大的外贸网站,WordPress网易云外链音《C程序设计基础教程》——刘厚泉,李政伟,二零一三年九月版,学习笔记 文章目录 1、指针的定义与初始化1.1、指针的定义1.2、指针的初始化 2、指针的使用2.1、指针运算符2.2、指针变量的运算 3、指针与数组3.1、指针与一维数组3.2、指针与二维…

在这里插入图片描述

《C++程序设计基础教程》——刘厚泉,李政伟,二零一三年九月版,学习笔记


文章目录

  • 1、指针的定义与初始化
    • 1.1、指针的定义
    • 1.2、指针的初始化
  • 2、指针的使用
    • 2.1、指针运算符
    • 2.2、指针变量的运算
  • 3、指针与数组
    • 3.1、指针与一维数组
    • 3.2、指针与二维数组
  • 4、指针与字符串
  • 5、指针与函数
    • 5.1、指针作为函数参数
    • 5.2、指针作为函数返回值
  • 6、引用
    • 6.1、引用的定义
    • 6.2、引用的使用
  • 7、应用实例

1、指针的定义与初始化

指针就是内存中的地址,它可能是变量的地址,也可能是函数的入口地址

变量可以理解为一种“直接访问”方式

在这里插入图片描述

指针则是提供了一种“间接访问”方式

在这里插入图片描述

1.1、指针的定义

指针是一种变量类型,它存储了另一个变量的内存地址。

指针变量所指向的那个空间为目标变量。

指针的定义通常使用星号(*)符号。

数据类型 *指针变量名;

编译器不允许指针变量里存放普通的数值和字符。

定义指针的时候给出的数据类型,不是指针变量的类型,而是指针所指向的空间里存放的数据的类型,即目标变量的类型。

32 位系统为例,每个指针变量在内存中占有4个字节的空间。

#include <iostream>
using namespace std;int main() 
{int a = 3;int *p = &a; // 定义指针变量 p,指向已存在的变量acout << p << endl; // a 变量的地址cout << &a << endl; // a 变量的地址cout << *p << endl; // a 变量的值return 0;
}

output

0x75d81ff694
0x75d81ff694
3

1.2、指针的初始化

定义的时候必须初始化,初始化必须是个地址,地址必须合法,目标变量的类型与指针变量定义时的类型必须相符;

注意事项:

  • 避免未初始化的指针:未初始化的指针可能导致程序崩溃或未定义行为。
  • 释放动态分配的内存:使用 new 分配的内存必须在不再需要时使用 delete 释放,以避免内存泄漏。
  • 指针运算:指针可以进行一些基本的算术运算,如指针加法和减法,但这些操作通常用于数组和动态内存管理。
#include <iostream>
using namespace std;int main() {int value = 10;int *ptr = &value;  // 定义并初始化指针cout << "Value: " << value << endl;cout << "Address of value: " << &value << endl;cout << "Value pointed by ptr: " << *ptr << endl;cout << "Address pointed by ptr: " << ptr << endl;// 修改指针指向的值*ptr = 20;cout << "New value: " << value << endl;// 动态分配内存int *dynamicPtr = new int;*dynamicPtr = 30;cout << "Value pointed by dynamicPtr: " << *dynamicPtr << endl;// 释放动态分配的内存delete dynamicPtr;// 指向空(nullptr)int *nullPtr = nullptr;if (nullPtr == nullptr) {cout << "nullPtr is pointing to nullptr" << endl;}// 指向数组的指针int arr[] = {1, 2, 3, 4, 5};int *ptrarr = arr;  // ptrarr 指向数组的第一个元素for(int i=0; i<5; i++){cout << *(ptrarr+i) << " ";}return 0;
}

outpu

Value: 10
Address of value: 0x670edffb44
Value pointed by ptr: 10
Address pointed by ptr: 0x670edffb44
New value: 20
Value pointed by dynamicPtr: 30
nullPtr is pointing to nullptr
1 2 3 4 5

2、指针的使用

2.1、指针运算符

(1)取地址运算符 (&)

功能:获取变量的内存地址。

示例:int a = 5; int *ptr = &a; 在此例中,&a 返回变量 a 的内存地址,该地址随后被赋给指针 ptr。

(2)解引用(取内容、取值)运算符 (*)

功能:访问指针所指向的内存地址中的数据。

示例:int a = 5; int *ptr = &a; int b = *ptr; 在这里,*ptr 访问了 ptr 指向的内存地址(即 a 的地址)中的数据,即 5,然后该值被赋给变量 b。

#include <iostream>
using namespace std;int main() {int a = 3, b=13;int *ptr = &a;cout << "a的地址:" << ptr << " " << &a << endl;cout << "ptr的地址:" << &ptr << endl;cout << "a的值:" << *ptr << " " << a << endl;a = 4; cout << "a修改后的值:" << *ptr << " " << a << endl;*ptr = 5;cout << "a修改后的值:" << *ptr << " " << a << endl;ptr = &b;cout << "b的地址:" << ptr << " " << &b << endl;cout << "ptr的地址:" << &ptr << endl;cout << "b的值:" << *ptr << " " << b << endl;return 0;
}

output

a的地址:0xa859bffb9c 0xa859bffb9c
ptr的地址:0xa859bffb90
a的值:3 3
a修改后的值:4 4
a修改后的值:5 5
b的地址:0xa859bffb98 0xa859bffb98
ptr的地址:0xa859bffb90
b的值:13 13

访问变量 a 的值有两种方式,一种是直接访问 cout <<a; 一种是间接访问 cout<<*ptr;

2.2、指针变量的运算

(1)赋值运算

int a[] = {1,2,3,4,5};
int *p = a;
int *q = &a[0];

指针也是可以相互赋值的

#include <iostream>
using namespace std;int main() {int a =5;int *p = &a;int *q = p;cout << *q << endl;return 0;
}

output

5

注意 *p 出现在赋值 = 左边和右边的意义是不同的

右边取值,左边表示把赋值号右边的值赋值到新地址空间里

(2)指针算术运算符

包括加法 (+) 和减法 (-)。

功能:在指针所指向的数组元素间进行位置移动。

示例:假设 int arr[] = {1, 2, 3, 4, 5}; int *ptr = arr;,则 ptr + 1 将指针移动到数组的下一个元素,即 2 的位置。同样,ptr - 1 会将指针移回前一个元素,即 1 的位置。但需注意,指针算术是基于指针类型的大小来计算的。

两个指针变量相减,有意义,相加没有意义

#include <iostream>
using namespace std;int main() {int a[10] = {0};int *p = &a[1];int *q = &a[7];cout << q-p << endl;return 0;
}

output

6

(3)指针比较运算符

包括等于 (==)、不等于 (!=)、大于 (>)、小于 (<)、大于等于 (>=) 和小于等于 (<=)。

功能:比较两个指针是否指向相同的内存地址或它们之间的相对位置关系。

示例:int arr1[] = {1, 2}; int arr2[] = {3, 4}; int *ptr1 = arr1; int *ptr2 = arr2; 在此情境下,ptr1 != ptr2 将返回 true,因为 ptr1 和 ptr2 指向不同的内存地址。

(4)成员访问运算符 (->)

功能:通过指针访问对象的成员变量或成员函数。

示例:假设有一个结构体 struct MyStruct { int x; }; MyStruct obj; MyStruct *ptr = &obj;,则 ptr->x 可以用来访问 obj 的成员变量 x。

(5)空指针常量 (nullptr)

尽管 nullptr 本身不是一个运算符,但它是一个字面量,用于表示空指针。在C++11及更高版本中推荐使用 nullptr 替代 NULL 或 0,以提高代码的可读性和类型安全性。

3、指针与数组

3.1、指针与一维数组

(1)数组名作为指针

在大多数情况下,数组名会被编译器解释为指向数组第一个元素的指针。例如,如果有一个数组 int arr[10];,那么 arr 实际上是指向 arr[0] 的指针。

(2)数组访问

你可以使用下标来访问数组元素,如 arr[i]

你也可以使用指针算术来访问数组元素,如 *(arr + i)

(3)数组名与指针的区别

类型不同:

数组名表示的是整个数组的类型,而指针表示的是指向某种类型的指针。例如,int arr[10]; 中 arr 的类型是 int[10],而 int* ptr = arr; 中 ptr 的类型是 int*。

常量性:

数组名是一个常量表达式,不能被修改(即你不能让数组名指向另一个地址)。例如,arr = anotherArray; 是非法的。

指针可以被修改以指向不同的地址。

#include <iostream>
using namespace std;int main() {char a[10] = "";for(int i=0; i<10; i++)*(a+i) = 97+i;char *p = a;for(int i=0; i<10; i++)cout << p[i];cout << endl;for(int i=0; i<10; i++)cout << *(p+i);cout << endl;for(int i=0; i<10; i++)cout << a[i];cout << endl;for(int i=0; i<10; i++)cout << *(a+i);cout << endl;return 0;
}

output

abcdefghij
abcdefghij
abcdefghij
abcdefghij

eg 利用指针操作数组里面的元素

#include <iostream>
using namespace std;int main() {int a[10] = {0};int *p = a;int *q = &a[9];for(int i=0; p<=q; p++)*p = i++;cout << p << " " << &a[9] << endl; // p 指向了数组后面一个内存单元cout << *p << endl; // 此时 p 已经是野指针了cout << *(p-1) << endl;p = a; // 重新赋值下for(int i=0; i<10; i++)cout << p[i]<< " "; for(int j=0; p<q; p++, q--) // 实现数组元素交换顺序{int tmpt;tmpt = *p;*p = *q;*q = tmpt;}cout << endl;for(int i=0; i<10; i++)cout << *(a+i)<< " "; return 0;
}

output

0xa763fffae8 0xa763fffae4
-668723975
9
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0

3.2、指针与二维数组

二维数组本质上是一个数组的数组,即每个元素本身也是一个数组。当使用指针处理二维数组时,情况会变得稍微复杂一些,因为你需要处理两个级别的指针:一个是指向数组(即行)的指针,另一个是指向数组内元素(即列)的指针。

(1)指向数组元素的指针

#include <iostream>
using namespace std;int main() {int a[3][4] = {{1,2,3,4}, {5,6,7,8},{9,10,11,12}};int *p = &a[2][2];for(int i=0; i<3; i++)for(int j=0; j<4; j++)cout << a[i][j]<<" ";cout << endl;for(; p<=&a[2][3]; p++)cout << *p <<" ";cout << endl;p = &a[2][2];for(; p>=&a[0][0]; p--)cout << *p <<" ";return 0;
}

output

1 2 3 4 5 6 7 8 9 10 11 12 
11 12
11 10 9 8 7 6 5 4 3 2 1

在这里插入图片描述

(2)指向一维数组的指针

指向一维数组的指针简称数组指针

数据类型 (*指针变量名)[数组长度]
int a[3][4];
int (*p)[4] = a;

访问数组的方式有直接访问 a[i][j],也可以间接访问 *(*(p+i)+j) 或者 *(*(a+i)+j)

+i 行指针、+j 列指针

在这里插入图片描述

eg 6-4 求矩阵的转置

#include <iostream>
#include<iomanip>
using namespace std;int main() {int a[3][3] = {{1,2,3}, {4,5,6},{7,8,9}};//int (*p)[3] = &a[0];int (*p)[3];p = a;for(int i=0; i<3; i++){for(int j=i; j<3; j++){int tmp;tmp = *(*(p+i)+j);*(*(p+i)+j) = *(*(p+j)+i);*(*(p+j)+i) = tmp;}}for(int i=0; i<3; i++){for(int j=0; j<3; j++)cout << setw(5) << a[i][j] << " ";cout << endl;}    return 0;
}

output

    1     4     7 2     5     83     6     9

注意这里的 for(int j=i; j<3; j++) 的初始值,第 i 次循环,第 i 行和第 i 列 完成交换

行指针可以定义为 int (*p)[3] = &a[0];,也可以定义为 int (*p)[3]; p = a;


上面的例子换成指向数组元素的指针实现

#include <iostream>
#include<iomanip>
using namespace std;int main() {int a[3][3] = {{1,2,3}, {4,5,6},{7,8,9}};int *p = &a[0][0];for(int i=0; i<3; i++){for(int j=i; j<3; j++){int tmp;tmp = *(p + (i*3+j));*(p + (i*3+j)) = *(p + (j*3+i));*(p + (j*3+i)) = tmp;}}for(int i=0; i<3; i++){for(int j=0; j<3; j++)cout << setw(5) << a[i][j] << " ";cout << endl;}    return 0;
}

output

    1     4     7 2     5     83     6     9

4、指针与字符串

字符串是个常量指针,像数组一样

C风格字符串是以空字符(‘\0’)结尾的字符数组。

在C++中,它们通常通过字符指针来操作。

#include <iostream>
using namespace std;int main() {char arr[] = "hello world!";char *s1 = arr;const char *s2 = "hello world!"; // 不要 const 就是变量,编译系统会有警告 or 报错for(int i=0; i<12; i++)cout << *(s1+i) << " ";cout << endl;for(int i=0; i<12; i++)cout << *(s2+i) << " ";cout << endl;while(*s2 != '\0'){cout << *s2 << " ";s2++;}return 0;
}

字符串是个常量指针

所以 const char *s2 = "hello world!"; 这里的 const 很有必要,不然会 warning 或者报错

output

h e l l o   w o r l d ! 
h e l l o   w o r l d !
h e l l o   w o r l d !

#include <iostream>
using namespace std;int main() {const char *string = "I love China!";cout << *string << endl;cout << string << endl;cout << string + 7 << endl;int a[] = {1,2,3,4,5,6};cout << *a << endl;cout << a << endl;cout << a+3 << endl;return 0;
}

字符串是个常量指针,字符串可以直接 cout(因为存在 ‘\0’ 结束符),不用循环打印

output

I
I love China!
China!
1
0x59227ff770
0x59227ff77c

5、指针与函数

当函数调用时的实参是一个指针时,要求形参必须定义为与其类型相同的指针

5.1、指针作为函数参数

指针作为参数的好处在于,避免函数里重新开辟大量临时空间,因此往往将一些占用空间较大的变量通过指针传递到函数里

eg:建立表格,4个学生,根据学号索引,5 门成绩,要求求出每个学生的平均分以及每门课程所有学生的平均分,根据学号打印学生的成绩

#include <iostream>
#include<iomanip>
using namespace std;
#define row 5
#define col 7void infoinput(float (*p)[col])
{for(int i=0; i<row-1; i++){cout << "第" << i+1 << "个学生:";for(int j=0; j<col-1; j++)cin >> *(*(p+i)+j); }
}void avgstud(float *p)
{float sum = 0;int i = 0;for(i=1; i<col-1; i++) // 第一位为学号sum += *(p+i);*(p+i) = sum / (col-2);
}void avgcour(float (*p)[col], int cour)
{float sum = 0;int i;for(i=0; i<row-1; i++)sum += *(*(p+i) + cour);*(*(p+i) + cour) = sum / (row-1);
}void infoout(float (*p)[col], int num)
{cout << "学号为" << num << "的学生得分为:";for(int i=0; i<row-1; i++){if(*(*(p+i) + 0) == num)  // 1 == 1.0 是 ture 的{for(int j=1; j<col; j++)cout << *(*(p+i)+j) << " ";}}cout << endl;
}void printinfo(float (*p)[col])
{cout << "当前信息表如下:"<< endl;for(int i=0; i < row; i++){for(int j=0; j < col; j++)cout << setw(10) << *(*(p+i) + j) << setw(10);cout << endl;}cout << endl;
}int main() 
{float info[row][col] = {0.0};float (*p)[col] = &info[0];// 输入学生信息infoinput(p);printinfo(p);// 计算每个学生所有课程的平均分for(int i=0; i<row-1; i++)avgstud(p[i]);printinfo(p);// 计算每门课程所有学生的平均分for(int i=1; i<col; i++)avgcour(p, i);printinfo(p);int num;cout << "请输入需要查询的学号:";cin >> num;infoout(p, num);return 0;
}/*
1001 67 78 69 89 75
1002 77 76 89 69 66
1003 89 88 78 75 67
1004 78 67 77 80 69
*/

注意一维和二维数组传递操作时候的差异

output

1个学生:1001 67 78 69 89 752个学生:1002 77 76 89 69 663个学生:1003 89 88 78 75 674个学生:1004 78 67 77 80 69
当前信息表如下:1001        67        78        69        89        75         01002        77        76        89        69        66         01003        89        88        78        75        67         01004        78        67        77        80        69         00         0         0         0         0         0         0当前信息表如下:1001        67        78        69        89        75      75.61002        77        76        89        69        66      75.41003        89        88        78        75        67      79.41004        78        67        77        80        69      74.20         0         0         0         0         0         0当前信息表如下:1001        67        78        69        89        75      75.61002        77        76        89        69        66      75.41003        89        88        78        75        67      79.41004        78        67        77        80        69      74.20     77.75     77.25     78.25     78.25     69.25     76.15请输入需要查询的学号:1004
学号为1004的学生得分为:78 67 77 80 69 74.2 

上面用指针来实现函数参数传递,下面替换成数组来传递

#include <iostream>
#include<iomanip>
using namespace std;
#define row 5
#define col 7void infoinput(float p[][col])
{for(int i=0; i<row-1; i++){cout << "第" << i+1 << "个学生:";for(int j=0; j<col-1; j++)cin >> p[i][j]; }
}void avgstud(float p[])
{float sum = 0;int i = 0;for(i=1; i<col-1; i++) // 第一位为学号sum += p[i];p[i] = sum / (col-2);
}void avgcour(float p[][col], int cour)
{float sum = 0;int i;for(i=0; i<row-1; i++)sum += p[i][cour];p[i][cour] = sum / (row-1);
}void infoout(float p[][col], int num)
{cout << "学号为" << num << "的学生得分为:";for(int i=0; i<row-1; i++){if(p[i][0] == num)  // 1 == 1.0 是 ture 的{for(int j=1; j<col; j++)cout << p[i][j] << " ";}}cout << endl;
}void printinfo(float p[][col])
{cout << "当前信息表如下:"<< endl;for(int i=0; i < row; i++){for(int j=0; j < col; j++)cout << setw(10) << p[i][j] << setw(10);cout << endl;}cout << endl;
}int main() 
{float info[row][col] = {0.0};// 输入学生信息infoinput(info);printinfo(info);// 计算每个学生所有课程的平均分for(int i=0; i<row-1; i++)avgstud(info[i]);printinfo(info);// 计算每门课程所有学生的平均分for(int i=1; i<col; i++)avgcour(info, i);printinfo(info);int num;cout << "请输入需要查询的学号:";cin >> num;infoout(info, num);return 0;
}

注意一维和二维数组传递操作时候的差异

output

1个学生:1001 67 78 69 89 752个学生:1002 77 76 89 69 663个学生:1003 89 88 78 75 674个学生:1004 78 67 77 80 69
当前信息表如下:1001        67        78        69        89        75         01002        77        76        89        69        66         01003        89        88        78        75        67         01004        78        67        77        80        69         00         0         0         0         0         0         0当前信息表如下:1001        67        78        69        89        75      75.61002        77        76        89        69        66      75.41003        89        88        78        75        67      79.41004        78        67        77        80        69      74.20         0         0         0         0         0         0当前信息表如下:1001        67        78        69        89        75      75.61002        77        76        89        69        66      75.41003        89        88        78        75        67      79.41004        78        67        77        80        69      74.20     77.75     77.25     78.25     78.25     69.25     76.15请输入需要查询的学号:1004
学号为1004的学生得分为:78 67 77 80 69 74.2 

eg 6-8 将3个元素按照从小到大排序,利用指针实现

#include <iostream>
using namespace std;void exc(int *x, int *y)
{ if(*x > *y){int z;z = *x;*x = *y;*y = z;}
}int main() 
{int a=9, b=3, c=6;int *i = &a;int *j = &b;int *k = &c;exc(i,j);exc(j,k);exc(i,k);cout << a << " " << b << " " << c << endl; return 0;
}

output

3 6 9

5.2、指针作为函数返回值

节省临时拷贝变量的空间,可以采用指针作为返回值

eg:输入两个字符串,返回字符串 s1 中第一次出现字符串 s2的头字符位置

#include <iostream>
using namespace std;char *subchar(char *s1, char *s2)
{int len1=0, len2=0;char *p1 = s1;char *p2 = s2;while(*p1 != '\0') // 求字符串长度{len1 ++;p1++;}cout << len1 << endl;while(*p2 != '\0') // 求字符串长度{len2 ++;p2++;}cout << len2 << endl;p1 = s1;p2 = s2;int match = 0;for(int i=0; i<len1; i++) // 遍历字符串 s1{if(*p1 == *p2) // 如果字符相等,s2 指针后移一个字符{p2++;}else // 如果不相等,重置字符串 s2{p2 = s2;}p1++; // s1 每一次比较都后移一次if(*p2 =='\0')  // 如果 s2 指针遍历结束了,说明 s1 中有对应的子串,输出结果return p1-len2;}return nullptr;
}int main() 
{char s1[] = "alsdufioabcaeoiuiojadl";char s2[] = "abc";char *p1 = s1;char *p2 = s2;char *result = subchar(p1, p2);cout << result - s1 + 1; // 首位置为 1return 0;
}

output

22
3
9

指针作为函数返回值的时候注意事项

  • 接收函数返回值的指针必须与返回值类型相符;
  • 返回的地址必须是一个合法的地址,即实际存在的空间首地址;

6、引用

引用(Reference)是一种复合类型,它允许你为一个已存在的对象创建一个新的名字。

引用就是给变量取别名,因此引用是变量的同义词,是变量本身。

对引用的任何操作实际上就是对其所代表的变量的改动。

引用在函数参数传递、返回值以及操作复杂数据结构时非常有用。

6.1、引用的定义

引用运算符 &

数据类型 &引用名 = 变量名;

eg

#include <iostream>
using namespace std;int main() 
{int a = 10;int &ref = a; // ref 是 a 的引用ref = 20;cout << a << endl;return 0;
}

output

20

引用在创建时必须被初始化,并且一旦被初始化后,它就不能再改变指向另一个对象。

6.2、引用的使用

1)单独使用

2)作为函数参数使用

3)作为函数返回值使用

eg 独立引用

  • 引用型变量在定义的时候必须初始化

  • 被引用的对象必须已经分配了空间,即不能为空或空指针

  • 被引用的对象不能为地址,即指针变量、数组变量等不能被引用

eg

int a[] = {10};
int &b = a;

会报错


eg

int a[] = {10};
int *p = a;
int &q = p;

会报错


eg 6-10 引用变量的单独使用

#include <iostream>
using namespace std;int main() 
{int a = 10;int &b = a;cout << "被引变量的地址:" << &a << endl;cout << "引用型变量的地址:" << &b << endl;b = 20;cout << "b赋值20后,a的值为:" << a << endl;a = 30;cout << "a赋值30后,b的值为:" << b << endl;return 0;
}

output

被引变量的地址:0xc0be9ffab4
引用型变量的地址:0xc0be9ffab4
b赋值20后,a的值为:20
a赋值30后,b的值为:30

引用变量在函数中使用时可以实现调用函数与被调函数间数据的“双向传值”

引用函数的返回值作为引用,则返回的不仅是一个值,还可以将函数调用结果当作“变量”来进行使用

eg

#include <iostream>
using namespace std;int& findMax(int &a, int &b) {return (a > b) ? a : b;
}int main() {int x = 5, y = 10;int &maxRef = findMax(x, y);cout << maxRef << endl; // 输出 10maxRef = 20; // 这也会修改 y 的值cout << y << endl; // 输出 20return 0;
}

output

10
20

eg 6-11

#include <iostream>
using namespace std;int k = 56;void f1(int a, int &b)
{cout << "in func f1 begin, a and b is " << a << " " << b << endl;a += 10;b += 10;cout << "in func f1 end, a and b is " << a << " " << b << endl;
}int &f2(int &a, int &b)
{cout << "in func f2, a+b=" << a+b << endl;if ((a+b) % 2 == 0)return a;elsereturn b;
}int main() 
{int x=1,y=2,z=3,w=0;f1(x,y);cout << "func f1, x and y is " << x << " " << y << endl; // 1, 12cout << "func f1, z k and w is " << z << " " << k << " " << w << endl; // 3,56,0w = f2(z,k)++;cout << "func f2, z k and w is " << z << " " << k << " " << w << endl; // 3,57, 56w = f2(z,k)++;cout << "func f2, z k and w is " << z << " " << k << " " << w << endl; // 4, 57, 3return 0;
}

output

in func f1 begin, a and b is 1 2
in func f1 end, a and b is 11 12
func f1, x and y is 1 12
func f1, z k and w is 3 56 0
in func f2, a+b=59
func f2, z k and w is 3 57 56
in func f2, a+b=60
func f2, z k and w is 4 57 3

注意 f2 第一次调用的时候,返回的是引用变量 k, k 赋值给 w 以后,然后自增

f2 第二次调用的时候,返回的是引用变量 z, z 赋值给 w 以后,然后自增

函数的返回值为引用时,不能返回局部变量的引用,不然返回函数内部 new 分配的内存的引用


总结

  • 引用在内部是通过指针实现的,但引用在语法上更安全、更简洁。

  • 引用通常比指针更受欢迎,因为它们不容易出错,并且代码更易于阅读和维护。

  • 当使用引用时,确保引用的对象在引用的生命周期内始终有效,以避免悬挂引用(dangling reference)问题。

7、应用实例

eg 6-12,给出一个浮点型数组,保留整数部分,求出小数部分的最大值

#include <iostream>
using namespace std;// 分离小数的整数和小数部分
void split(double x, int *intp, double *fracp)
{*intp = int(x);*fracp = x - *intp;
}// 保留数组的整数部分,求出小数部分的最大值
double f(double *p, int n)
{int i, intp;double fracp, maxfracp=0;for(i=0; i<n ;i++){split(*(p+i), &intp, &fracp);if(fracp > maxfracp)maxfracp = fracp;*(p+i) = intp;}return maxfracp;
}int main() {int i;double maxfr, a[6]={1.1, 2.2, 3.3, 9.9, 6.6, 5.0};maxfr = f(a, 6);for(i=0; i<6; i++)cout << *(a+i) << " ";cout << endl << maxfr;return 0;
}

output

1 2 3 9 6 5 
0.9

eg 6-13 n 个人,1,2,3 重复报数,报到 3 就淘汰,游戏直到剩下最后一个人才结束

#include <iostream>
using namespace std;int main() 
{int n = 23; // 参与游戏的总人数int a[n] = {0};int zeronum = 0; // 淘汰的人数int num = 0; // 0,1,2 循环计数int index =0; // 循环报数while(n - zeronum > 1) // 淘汰到只剩下一个人的时候退出{   if(index==n) // 如果所有人循环完,第一个人重新续上index = 0;if (a[index] == -1) // 如果人被淘汰,跳过{index ++;continue;}if(num==2) // 如果报数到了2,就会被淘汰{a[index] = -1; // 淘汰num=0; // 报数置为0index ++; // 下一位zeronum++; // 淘汰数量 +1continue;}num++; // 正常情况下报数 +1index++; // 下一位游戏玩家}for(int i=0; i<n; i++)if(a[i] != -1)cout << i+1 << " "; //return 0;
}

output

8 

以 23 个人为例

第一轮

1 2 x 4 5 x 7 8 x 10 11 x 13 14 x 16 17 x 19 20 x 22 23

第二轮

x 2 x 4 x x 7 8 x x 11 x 13 x x 16 17 x x 20 x 22 x

第三轮

x 2 x 4 x x x 8 x x 11 x x x x 16 17 x x x x 22 x

第四轮

x 2 x x x x x 8 x x 11 x x x x x 17 x x x x 22 x

第五轮
x x x x x x x 8 x x 11 x x x x x x x x x x 22 x

第六轮
x x x x x x x 8 x x x x x x x x x x x x x 22 x

第七轮
x x x x x x x 8 x x x x x x x x x x x x x x x


以 30 个人为例

1 2 x 4 5 x 7 8 x 10 11 x 13 14 x 16 17 x 19 20 x 22 23 x 25 26 x 28 29 x

1 2 x x 5 x 7 x x 10 11 x x 14 x 16 x x 19 20 x x 23 x 25 x x 28 29 x

x 2 x x 5 x x x x 10 11 x x x x 16 x x 19 x x x 23 x 25 x x x 29 x

x 2 x x x x x x x 10 11 x x x x x x x 19 x x x 23 x x x x x 29 x

x 2 x x x x x x x x 11 x x x x x x x 19 x x x x x x x x x 29 x

x 2 x x x x x x x x x x x x x x x x 19 x x x x x x x x x 29 x

x x x x x x x x x x x x x x x x x x 19 x x x x x x x x x 29 x

x x x x x x x x x x x x x x x x x x x x x x x x x x x x 29 x

int n =30; 

output

29

上述例子用指针的形式表示如下

#include <iostream>
using namespace std;int main() 
{int n = 30; // 参与游戏的总人数int a[n] = {0};int *p = a;int zeronum = 0; // 淘汰的人数int num = 0; // 0,1,2 循环计数int index =0; // 循环报数while(n - zeronum > 1) // 淘汰到只剩下一个人的时候退出{   if(index==n) // 如果所有人循环完,第一个人重新续上index = 0;if (*(p+index) == -1) // 如果人被淘汰,跳过{index ++;continue;}if(num==2) // 如果报数到了2,就会被淘汰{*(p+index) = -1; // 淘汰num=0; // 报数置为0index ++; // 下一位zeronum++; // 淘汰数量 +1continue;}num++; // 正常情况下报数 +1index++; // 下一位游戏玩家}for(int i=0; i<n; i++)if(*(p+i) != -1)cout << i+1 << " "; //return 0;
}

eg 6-14 在一串名字中给出一个名字,求其在这串名字中的位置

#include <iostream>
using namespace std;int search(char(*p)[31], int n, const char* pname)
{int j;for(int i=0; i<n; i++) // 遍历每个名字{for(j=0; j<31; j++){if (*(*(p+i)+j)=='\0' && *(pname+j)=='\0') // 如果字符都遍历完了还没有退出,表示名字相等return j;if (*(*(p+i)+j) != *(pname+j)) // 名字中的字符不相等,比对下一个名字break;}}return 0;}int main() 
{int n = 10;char name[n][31] = {"name1", "name2", "name3", "name4", "name5", "name6", "name7", "name8", "name9", "name10",}; const char *pname = "name5";int result = search(name, 10, pname);cout << result;return 0;
}

output

5

可以看到 name5 在第五个位置

调用字符串比较接口 strcmp 试试

#include <iostream>
#include<string.h>
using namespace std;int search(char(*p)[31], int n, const char* pname)
{for(int i=0; i<n; i++) // 遍历每个名字{if(strcmp(*(p+i), pname)==0)return i+1;}return 0;}int main() 
{int n = 10;char name[n][31] = {"name1", "name2", "name3", "name4", "name5", "name6", "name7", "name8", "name9", "name10",};const char *pname = "name5";//char pname[] = {"name5"};int result = search(name, 10, pname);cout << result;return 0;
}

output

5

或者 char pname[] = {"name5"};,对应形参 int search(char(*p)[31], int n, char* pname)


eg 6-15 输入三个字符串,按由大到小输出

#include <iostream>
using namespace std;void cmp(char *&p1, char *&p2)
{for(int i=0; i<20; i++){if (*(p1+i) == *(p2+i))continue;if (*(p1+i) > *(p2+i))return;if (*(p1+i) < *(p2+i)){char *tmp;tmp = p1;p1 = p2;p2 = tmp;return;}}
}int main() 
{char a1[20] = "windows";char a2[20] = "yesterday";char a3[20] = "apple";char * p1 = a1;char * p2 = a2;char * p3 = a3;cmp(p1, p2);cmp(p1, p3);cmp(p2, p3);cout << p1 << " " << p2 << " " << p3 << endl;return 0;
}

output

yesterday windows apple

函数定义这里的引用 void cmp(char *&p1, char *&p2) 尤为关键

特别注意:少了引用,指针都是临时变量,退出函数的时候会释放掉,没有达到交换的目的,因为我们是对指针操作,而不是指针所指向空间的值操作

再来个数组为例

#include <iostream>
using namespace std;void cmp(int *&p1, int *&p2)
{for(int i=0; i<3; i++){if (*(p1+i) == *(p2+i))continue;if (*(p1+i) > *(p2+i))return;if (*(p1+i) < *(p2+i)){int *tmp;tmp = p1;p1 = p2;p2 = tmp;return;}}
}int main() 
{int a1[3] = {1,2,3};int a2[3] = {0,1,2};int a3[3] = {1,3,4};int * p1 = a1;int * p2 = a2;int * p3 = a3;cmp(p1, p2);cmp(p1, p3);cmp(p2, p3);for(int i=0; i<3; i++)cout << p1[i] << " ";cout << endl;for(int i=0; i<3; i++)cout << p2[i] << " ";cout << endl;for(int i=0; i<3; i++)cout << p3[i] << " ";cout << endl;return 0;
}

output

1 3 4 
1 2 3
0 1 2
http://www.dtcms.com/wzjs/86137.html

相关文章:

  • 郑州网站建设华久营销型企业网站有哪些平台
  • 定制型和模板型网站长沙seo推广优化
  • wordpress写真图片主题来客seo
  • 苏州协会网站建设在线观看的seo综合查询
  • 做羊水亲子鉴定网站长尾关键词排名推广
  • 怎样添加网站地图谷歌关键词分析工具
  • 网站建设属于高新技术收入吗seo搜索引擎优化营销案例
  • c 做网站怎么显示歌词个人博客seo
  • 站长工具查询网搜索引擎优化方法包括
  • 网站开发一般用什么软件营销案例最新
  • 空气炸锅做糕点的网站游戏代理平台一天结一次
  • 网站建设 bs模式电子商务seo实训总结
  • 可以做数学题的网站哈尔滨百度关键词优化
  • 表情包制作网站外链网盘系统
  • 网站建设赵玉敏郑州seo优化哪家好
  • 怎样在百度上作网站推广全网营销系统1700元真实吗
  • 靓号网站开发最新的即时比分
  • 哈尔滨网站制作哪家好薇seo网站快排
  • 旅游网站系统功能百度学术查重
  • cms 美容网站 模版最新长尾关键词挖掘
  • php购物网站设计代码app拉新推广赚佣金
  • 关于网站设计的毕业论文题目郑州网站关键词优化公司哪家好
  • 做微信小程序的网站外包seo服务口碑好
  • 网站内部资源推广怎么做百度天眼查
  • 成都 企业网站建设公司外链论坛
  • 广州印刷网站建设百度热搜榜历史
  • 武汉找人做网站微信软文模板
  • 高端网站建设高端网站建设专家网站推广平台排行
  • 国内简约网站网络热词2021
  • 网站开发的研究现状正规的关键词优化软件