首页 > 编程语言 >C++学习路线(十五)

C++学习路线(十五)

时间:2024-10-15 14:46:26浏览次数:9  
标签:arr int C++ 路线 ++ 十五 数组 secondValue 指针

多级指针

#include <iostream>
using namespace std;

int main() {
	int block1 = 888;
	int *block2 = &block1;
	int** block3 = &block2;
	int*** block4 = &block3;
	int**** block5 = &block4;

	cout << "block2:" << *block2 << endl;
	cout << "block3:" << **block3 << endl;
	cout << "block4:" << ***block4 << endl;
	cout << "block5:" << ****block5 << endl;
	return 0;
}

指针表示法和数组表示法

我们可以用数组或者指针来访问数组

int main() {
	int months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	int len = sizeof(months) / sizeof(months[0]);
	for (int i = 0; i < len; i++) {
		//数组表示法
		cout << "months[" << i << "] = " << months[i] << endl;
		//指针表示法
		int* p = months;
		cout << "*(p + " << i << ") = " << *(p + i) << endl;
	}
	return 0;
}

练习一

我们需要完成一个需求,寻找二维数组中第一大的数字和第二大的数字。

1.记得处理边界情况 如果数组元素<=1 则不合法

2.设置两个变量,第一个变量是记录最大的值first , 第二个变量是记录次大的值second

        输入总行数 总列数

        将数据输入到二维数组里面

        然后处理<=1 的情况

        比较nums[0][0] 和nums[0][1] 的值 赋值给first 和 second

        然后for(int i = 0 ; i < m *n  ; i ++ ){

                如果second >= nums[i / (n)][i % (n)] 跳过

                如果second < nums[i / n][i % n]; && nums[i / n][i % n] <= first

                        second = nums[i] / n[i % n];

                如果first < nums[i / n][i % n]

                        second = first;

                        first = nums[i / n][i % n];

}

#include <iostream>
using namespace std;
#define MAX_SIZE 128
int arr[MAX_SIZE][MAX_SIZE];
int main() {
	int m, n;
	cin >> m >> n;
	int firstValue , secondValue;
	if (m < 0 || n < 0 || m * n <= 1) {
		cout << "Invalid input" << endl;
		return 0;
	}
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> arr[i][j];
	if (arr[0][0] > arr[0][1]) {
		firstValue = arr[0][0];
		secondValue = arr[0][1];
	}else{
		firstValue = arr[0][1];
		secondValue = arr[0][0];
	}
	for (int i = 2; i < m * n; i++) {
		if (secondValue >= arr[i / n][i % n]) continue;
		if (firstValue < arr[i / n][i % n]) {
			secondValue = firstValue;
			firstValue = arr[i / n][i % n];
		}else{
			secondValue = arr[i / n][i % n];
		}
	}
	cout << "The second largest value is: " << secondValue << endl;
	cout << "The largest value is: " << firstValue << endl;
	return 0;
}

 使用指针的方法

#include <iostream>
using namespace std;
#define MAX_SIZE 128
int arr[MAX_SIZE][MAX_SIZE];
int main() {
	int m, n;
	cin >> m >> n;
	int *firstValue , *secondValue;
	if (m < 0 || n < 0 || m * n <= 1) {
		cout << "Invalid input" << endl;
		return 0;
	}
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> arr[i][j];
	if (arr[0][0] > arr[0][1]) {
		*firstValue = arr[0][0];
		*secondValue = arr[0][1];
	}else{
		*firstValue = arr[0][1];
		*secondValue = arr[0][0];
	}
	for (int i = 2; i < m * n; i++) {
		if (*secondValue >= arr[i / n][i % n]) continue;
		if (*firstValue < arr[i / n][i % n]) {
			*secondValue = *firstValue;
			*firstValue = arr[i / n][i % n];
		}else{
			*secondValue = arr[i / n][i % n];
		}
	}
	cout << "The second largest value is: " << secondValue << endl;
	cout << "The largest value is: " << firstValue << endl;
	return 0;
}

我们如何用指针数组的方式遍历数组

第一种方式:

int A[4][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };
int (*p)[3] = &A[0]; // 定义一个指向三个成员的数组的指针
for (int i = 0; i < 4; i++) {
	for (int j = 0; j < 3; j++)
		cout << (*p)[j] << " ";
	cout << endl;
	p++; // 指向下一个数组
}

第二种方式:

int A[4][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };
int* p = NULL;
for (int i = 0; i < 4; i++) {
	p = A[i];
	for(int j = 0 ; j < 3 ; j ++ )
		cout << *(p + j) << " ";
	cout << endl;
}

练习二

找二维数组里值最小的数
#include <iostream>
using namespace std;

int main() {
	int A[4][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };
	int (*p)[3] = &A[0];
	int* boy = &(*p)[0];
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 3; j++)
			if (*boy > *((*p) + j)) {
				boy = &(*p)[j];
			}
		p++;
	}
	cout << *boy << endl;
	return 0;
}

数组与指针的区别

数组:数组是用于储存多个相同类型数据的集合。
指针:指针是一个变量,但是它和普通变量不一样,它存放的是其它变量在内存中的地址。
1.赋值
数组:只能一个一个元素的赋值或拷贝
指针:指针变量可以相互赋值
2.表示范围
数组有效范围就是其空间的范围,数组名使用下表引用元素,不能指向别的数组

指针可以指向任何地址,但是不能随意访问,必须依附在变量有效范围之内
3. sizeof数组:
数组所占存储空问的内存:sizeof(数组名)

数组的大小:sizeof(数组名)/sizeof(数据类型)
指针:
在 32位平台下,无论指针的类型是什么,sizeof(指针名)都是4.
在64位平台下,无论指针的类型是什么,sizeof(指针名)都是8.

指针数组和数组指针

指针数组:

        int *ptr[2]; // 定义一个两个元素的数组 数组元素是指针变量

        int salary1 = 1 , salary2 = 2;

        ptr[0] = &salary1;

        ptr[1] = &salary2;

数组指针:

int (*p)[3]; //定义了一个指向三个成员的数组的指针

访问元素的两个方式

int A[4][3] = { {省略}};

数组表示法:(*p)[j];

指针表示法:*((*p) + j)

传参

数组传参时,会退化为指针!

(1)退化的意义:C语言只会以值拷贝的方式传递参数,参数传递时,如果只拷贝整个数组,效率会大大降低,并且在参数位于栈上,太大的数组拷贝将会导致溢出。

(2)因此C语言将数组的传参进行了退化。将整个数组拷贝一份传入函数时,将数组名看做常量指针,传数组首元素的地址。

我们还可以使用指针数组访问数组元素

#include <iostream>
using namespace std;

void method(int* arr[], int size) {
	for(int i = 0 ; i < size ; i ++ )
		cout << *(arr[i]) << " ";
	cout << endl;
}

int main() {
	int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int* arrPtr[10] = { 0 };
	for (int i = 0; i < 10; i++) {
		arrPtr[i] = &arr[i];
	}
	method(arrPtr, 10);
	return 0;
}

使用指针数组来进行访问

*(arr + i) 解引用 是一个指针 然后再解引用*得到值

#include <iostream>
using namespace std;

void method(int** arr, int size) {
	for (int i = 0; i < size; i++)
		cout << *(*(arr + i)) << " ";
}

int main() {
	int arr[5] = { 1, 2, 3, 4, 5 };
	int* arrPtr[5] = { 0 };
	for (int i = 0; i < 5; i++)
		arrPtr[i] = &arr[i];
	method(arrPtr, 5);
	return 0;
}

二维数组的访问方式

利用指针数组 new方式

#include <iostream>
using namespace std;

void processArray(int** arr, int rows, int cols) {
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            cout << "arr[" << i << "][" << j << "] = " << arr[i][j] << endl;
        }
    }
}
int main() {
    int arr[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    // 创建一个指向每一行的指针数组
    int** ptrArr = new int* [3];
    for (int i = 0; i < 3; ++i) {
        ptrArr[i] = arr[i]; // 每个ptrArr[i]指向arr[i]
    }
    processArray(ptrArr, 3, 4); // 传递指针数组到函数
    delete[] ptrArr; // 释放动态分配的内存
    return 0;
}

指针相加减

(1) 使用“指针-指针”的方式计算整数数组元素的偏移值
(2) 使用“指针-指针”的方式计算字符串元素的偏移值

int ages[] = {20, 25, 30, 35, 40};
int len = sizeof(ages) / sizeof(ages[0]);
int* martin = ages + 1;
int* john = ages + 2;
cout << "martin address:" << martin << " " << *martin << endl;
cout << "john address:" << john << " " << *john << endl;
cout << "martin - john:" << john - martin << endl;

指针-指针是直接计算偏移值 不是计算相差字节数

但是不允许指针相加,只允许+一个常量 或者 一个枚举常量

知识点:
(1)指针和指针可以做减法操作,但不适合做加法运算;
(2)指针和指针做减法适用的场合:两个指针都指向同一个数组,相减结果为两个指针之间的元素数目,而不是两个指针之间相差的字节数。
比如:intint array[4]={12,34, 56, 78};
int *p int1= &int array[0];
int *p int2 = &int array[3];
p_int2-p_int1 的结果为 3,即是两个之间之间的元素数目为3个。
如果两个指针不是指向同一个数组,它们相减就没有意义。

(3)不同类型的指针不允许相减,比如
char *pl;
imnt *p2;
p2-p1是没有意义的。 

标签:arr,int,C++,路线,++,十五,数组,secondValue,指针
From: https://blog.csdn.net/weixin_45169583/article/details/142926881

相关文章

  • Ubuntu中VSCode配置CC++环境
    我的环境:Ubuntu22.04.5LTSVSCode版本:1.94.2参考文章:https://blog.csdn.net/zimuzi2019/article/details/106861692https://zhuanlan.zhihu.com/p/147366852一、安装gcc/g++和gdbsudoapt-getupdatesudoapt-getinstallgccsudoapt-getinstallg++sudoa......
  • day03(C++)信号槽
    目录1.概念2.函数原型3.连接方式3.1自带信号→自带槽3.2自带信号→自定义槽3.3自定义信号4.信号槽传参5.对应关系5.1一对多5.2多对一信号槽1.概念之前的程序界面只能看,不能交互,信号槽可以让界面进行人机交互。信号槽是Qt在C++基础上新增的......
  • RBE104TC C/C++ Programming Language
    RBE104TCC/C++ProgrammingLanguageAssignment1ContributiontotheOverallMarks30%IssueDateSubmissionDeadline13thOctober2024AssignmentOverview:ThisassignmentisgearedtowardsassessingfundamentalcodingconceptsinC/C++andinitiatingthep......
  • c++基础语法知识
    基础当VS中一个项目下有两个及以上的源文件时,编译会产生错误:main已经在test.obj中定义;找到一个或多个多重定义的符号。**解决办法:**将不需要编译的源文件排除:右键“属性”,将“从生成中排除”选择“是”,保存后再运行需要运行的源文件就可以成功,且被排除的文件右下角有红标......
  • C++面试速通宝典——27
    504.孤儿进程和僵尸进程是什么?怎么处理?孤儿进程:当一个父进程结束,而他的一个或多个子进程还在运行时,那些子进程将成为孤儿进程。孤儿进程会被init进程(进程ID为1)自动领养,init进程会负责调用wait()来收集他们的退出状态。僵尸进程:当一个子进程结束,在其父进程没有调用wait()......
  • C++试题带答案
    一、选择填空题1.有如下定义structperson{char name[9];intage;};person  pr[10]={"Johu",17,"Paul",19,"Mary",18,"Adam",16};根据上述定义,能输出字母M的语句是     A)cout<<pr[3].mane;          B)cout<<pr[3].name[1];C......
  • 【C++指南】C++中的浅拷贝与深拷贝:深入剖析
              ......
  • 网络安全系统教程+渗透测试+学习路线(自学笔记)_渗透测试工程师怎么自学
    一、什么是网络安全网络安全可以基于攻击和防御视角来分类,我们经常听到的“红队”、“渗透测试”等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面性,例如Web安全技术,既有Web渗透,也......