从零起步学C++笔记(三)-数组与指针

1 数组

1.1 一维数组

1.1.1 一维数组的定义方式

语法如下

  1. 数据类型 数组名[ 数组长度 ];
  2. 数据类型 数组名[ 数组长度 ]={值1,值2,···};
  3. 数据类型 数组名[ ]={值1,值2,···};

数组的特点

  • 数组存放在连续的内存空间中
  • 数组中的每个元素是相同的数据类型
  • 下标从0开始

arr

102030405060
arr[0]arr[1]arr[2]arr[3]arr[4]arr[5]
#include<iostream>
using namespace std;

int main(){
	/*
	> 1. 数据类型 数组名[ 数组长度 ];
	> 2. 数据类型 数组名[ 数组长度 ]={值1,值2,···};
	> 3. 数据类型 数组名[ ]={值1,值2,···};
	*/
	//1. 数据类型 数组名[ 数组长度 ];
	int arr1[5];//写个数,下标从0到个数-1
	arr1[0] = 10;
	arr1[1] = 20;
	arr1[2] = 30;
	arr1[3] = 40;
	arr1[4] = 50;
	for (int i = 0; i < 5; i++)
	{
		cout << arr1[i] << endl;
	}
	//2. 数据类型 数组名[ 数组长度 ]={值1,值2,···};
	int arr2[5] = { 10,20,30 };
	//如果在初始化的时候没有全部初始化,会补零
	for (int i = 0; i < 5; i++)
	{
		cout << arr2[i] << endl;
	}
	//3. 数据类型 数组名[ ]={值1,值2,···};
	//定义数组的时候必须有初始长度
	int arr3[] = { 9,8,7,6,5,4,3,2,1 };
	for (int i = 0; i < 9; i++)
	{
		cout << arr3[i] << endl;
	}
	return 0;
}

1.1.2一维数组的数组名

数组名用途:

  • 获得数组在内存中的长度
  • 获取数组在内存中的首地址
#include<iostream>
using namespace std;

int main() {
	//通过数组名统计数组占用内存
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	cout << "数组占用的空间大小为" << sizeof(arr) << endl;
	cout << "每个元素占用的内存空间为:" << sizeof(arr[0]) << endl;
	cout << "数组长度为" << sizeof(arr) / sizeof(arr[0]) << endl;

	//获取数组首地址
	cout << "数组的首地址" << arr << endl;
        //(int)arr 可以查看十进制地址
	cout << "第一个元素的地址" << &arr[0] << endl;
        //首地址即为第一个元素的地址
	cout << "第二个元素的地址" << &arr[1] << endl;
	return 0;
}

例题 五只小猪称体重

一个数组记录了五只小猪的体重,输出最重的小猪

#include<iostream>
using namespace std;

int main() {
	//一个数组记录了五只小猪的体重,输出最重的小猪
	int arr[5] = { 300,350,200,400,250 };
	//打擂台找最大值

	//假想最大值为arr[0]
	int max = arr[0];
	
	//与后面逐个比较,如果有更大值就更新max
	for (int i = 1; i < 5; i++)
	{
		if (arr[i] > max) {
			max = arr[i];
		}
	}
	cout << "最大值为" << max << endl;
	return 0;
}

例题 数组元素逆序放置

例如 原数组为{1,2,3,4,5}则新数组为{5,4,3,2,1}

#include<iostream>
using namespace std;

int main() {
	//数组逆序
	int arr[] = { 1,2,3,4,5,6,7 };
	int length = sizeof(arr) / sizeof(arr[0]);
	//第一个和倒数第一个互换
	//第二个和倒数第二个互换
	//循环到中间位置
	for (int start = 0, end = length - 1; start <= end; start++, end--)
	{
		int temp;
		temp = arr[start];
		arr[start] = arr[end];
		arr[end] = temp;
	}
	//输出
	for (int i = 0; i < length; i++)
	{
		cout << arr[i] << endl;
	}
	
	return 0;
}

1.1.3 冒泡排序

步骤:

  • 1 比较相邻元素,如果第一个比第二个大,则交换位置。
  • 2 对每一个相邻的元素做同样的工作,n个数比n-1此,找到了最大值
  • 3 重复进行比较,每次比较次数-1,直到不需要比较
  • 轮数=数组长度-1
  • 每一轮比较次数=元素个数-当前轮数-1
#include<iostream>
using namespace std;

int main() {
	//数组逆序
	int arr[10] = { 3,6,8,2,5,7,9,6,1,7 };
	int length = sizeof(arr) / sizeof(arr[0]);
	
	//控制轮数	只要n-1次即可
	for (int k = 0; k < length-1; k++){
		//进行比较,第一轮n个数比较n-1次,第k轮要比较n-k-1次
		for (int i = 0; i < length -k- 1; i++){
			if (arr[i] > arr[i + 1]) {
				int temp = arr[i];
				arr[i] = arr[i + 1];
				arr[i + 1] = temp;
			}
		}
	}
	for (int i = 0; i < length; i++){
		cout << arr[i]<<endl;
	}
	return 0;
}

1.2 二维数组

1.2.1 二维数组的定义方式

有四种定义方式
语法如下

数据类型 数组名 [ 行数 ] [ 列数 ]

数据类型 数组名 [ 行数 ] [ 列数 ]={{值1,值2},{值3,值4}}

数据类型 数组名 [ 行数 ] [ 列数 ]={值1,值2,值3,值4,···}

数据类型 数组名 [ ] [ 列数 ]={值1,值2,值3,值4,···}

索引方式

arr [ i ] [ j ]

#include<iostream>
using namespace std;

int main() {
	//定义一个二维数组
	int arr1[2][3];
	arr1[0][0] = 1;
	arr1[0][1] = 2;
	arr1[0][2] = 3;
	arr1[1][0] = 4;
	arr1[1][1] = 5;
	arr1[1][2] = 6;
	//外层循环打印行,内层循环打印列
	for (int i = 0; i < 2 ; i++){
		for (int j = 0l; j < 3; j++) {
			cout << arr1[i][j]<<" ";
		}
		cout << "\n";//每一行打印后打印回车
	}

	int arr2[2][3] = { 
		{1,2,3},
		{4,5}
	};//定义时赋值 未赋值的为0
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 3; j++) {
			cout << arr2[i][j] << " ";
		}
		cout << "\n";//每一行打印后打印回车
	}
	//输出 
	//1 2 3
	//4 5 0

	int arr3[2][3] = { 1,2,3,4,5 };
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 3; j++) {
			cout << arr3[i][j] << " ";
		}
		cout << "\n";//每一行打印后打印回车
	}

	int arr4[][3] = { 1,2,3,4,5,6 };//列数不能省略,不能少写
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 3; j++) {
			cout << arr4[i][j] << " ";
		}
		cout << "\n";//每一行打印后打印回车
	}
	return 0;
}

1.2.2 二维数组的数组名

数组名用途:

  • 获得数组在内存中的大小
  • 获取数组在内存中的首地址
#include<iostream>
using namespace std;

int main() {
	int arr[2][3] = { 
		{1,2,3},
		{4,5,6}
	};

	cout << "二维数组占用的内存空间为" << sizeof(arr) << endl;
	//列数*行数*数据类型大小

	//输出二维数组第一行内存
	cout << "第一行占用的内存为" << sizeof(arr[0]) << endl;
	cout << "每一个元素占用的内存为" << sizeof(arr[0][0]) << endl;

	//获取数组的列数和行数
	cout << "数组的行数为" << sizeof(arr) / sizeof(arr[0]) << endl;
	cout << "数组的列数为" << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;
	
	//首地址就是第一个元素的地址
	cout << "二维数组首地址" << arr << endl;
	cout << "第一个元素的地址" << &arr[0][0] << endl;

	return 0;
}

2 指针

2.1 指针的基本概念

指针的作用:通过指针间接访问内存
指针存放的是地址。

2.2 指针的定义和使用

数据类型* 指针名

#include<iostream>
using namespace std;

int main() {
	int a = 10;
	int* p;

	//为指针赋值
	p = &a;//&为取地址

	cout << "a的地址为" << &a << endl;
	cout << "p的值为" << p << endl;//p的值为a的地址

	//*p 代表解开引用,可以访问到p指向的内存所存放的内容
	cout << "a=" << a << endl;
	cout << "p指向的内存存放的数为" << *p << endl;
	//p指向的内容是a的内容

	return 0;
}

2.3 指针类型的大

32位的操作系统下,指针类型占用4个字节

64位的操作系统下,指针类型占用8个字节

#include<iostream>
using namespace std;

int main() {
	int a = 10;
	int* p;

	//为指针赋值
	p = &a;

	cout << "int*所占的内存大小为" << sizeof(int*) << endl;
	cout << "p所占的内存大小为" << sizeof(p) << endl;
	return 0;
}

2.4 空指针和野指针

2.4.1 空指针:指针指向内存中编号为0的空间

用途:初始化指针变量

注意:空指针指向的内存不可访问

	//空指针
	int* p = NULL;

运行以下访问空指针的程序会出错

#include<iostream>
using namespace std;

int main() {
	
	//空指针
	int* p = NULL;

	//空指针不可以进行访问
	*p = 20;

	return 0;
}

在这里插入图片描述

2.4.2 野指针:指针指向非法的内存空间

直接指向并非我们申请的空间避免出现

#include<iostream>
using namespace std;

int main() {
	
	//野指针
	int* p = (int*)0x1100;
	cout<<*p<<endl;

	return 0;
}

2.5 const修饰指针

const修饰指针有三种情况

  • const修饰指针 常量指针
  • const修饰常量 指针常量
  • const既修饰指针 又修饰常量

2.5.1 const修饰指针 常量指针

即指向一个常量的指针。

const 数据类型* 指针名 = &变量名

特点:指针的指向可以修改,指针指向的值不能改。

2.5.2 const修饰常量 指针常量

即为指针类型的常量

数据类型* const 指针名 = &变量名

特点:指针指向的值可以修改,指针的指向不可以修改

2.5.3 const既修饰指针 又修饰常量

const 数据类型* const 指针名 = &变量名

特点:指向和值都不能修改

2.6 指针与数组

作用:利用指针访问数组中的每一个元素

#include<iostream>
using namespace std;

int main() {
	
	//
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };

	//定义一个指针,让其指向数组的首地址
	//数组名即代表了首地址
	int* p = arr;

	//输出第一个元素
	//*表示解开引用,得到指向的地址的值
	cout << *p << endl;;

	p++;//指针向后偏移

	//输出第二个元素
	cout << *p << endl;
	return 0;
}

2.7 指针与函数

2.7.1 值传递

值传递不影响实参的值。

2.7.2 地址传递

地址传递可以修改实参的值。

#include<iostream>
using namespace std;

//交换两个数字
void swap(int* p1, int* p2){
	//参数为两个指针,得到传入的地址

	//将指向的地址的值改变
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

int main() {
	
	//地址传递
	int a = 3, b = 5;
	//传入变量的地址
	swap(&a, &b);
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	return 0;
}

2.8 指针、数组与函数

封装一个函数,利用冒泡排序,对数组进行升序排序.
a r r = [ 3 , 7 , 9 , 4 , 5 , 7 , 1 , 0 , 4 , 6 ] arr=[3,7,9,4,5,7,1,0,4,6] arr=[3,7,9,4,5,7,1,0,4,6]

#include<iostream>
using namespace std;

//冒泡排序
void bubble_sort(int* arr,int length) {//形参为指针
	for (int k = 0; k < length-1; k++){
		for (int i = 0; i < length - k - 1; i++){
			if (arr[i] > arr[i + 1]) {
				int temp = arr[i];
				arr[i] = arr[i + 1];
				arr[i + 1] = temp;
			}
		}
	}
}

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

int main() {
	
	int arr[] = { 3,7,9,4,5,7,1,0,4,6 };
	int len = sizeof(arr) / sizeof(arr[0]);
	//arr即为首地址,用到了地址传递
	bubble_sort(arr, len);
	print_arr(arr, len);
	return 0;
}
  • 11
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值