2.0 数组与指针

你知道计算机为什么有32位和64位之分吗?

首先,计算机是以二进制进行运算和存储的。

每一个变量,在计算机中,都有其唯一的“地址”,而这地址就是用二进制来存储的。

一个0/1(二进制的一位)叫做一个比特(bit),八个比特叫做一个字节(b)。

一千个字节叫做kb,简称k;

一兆字节叫做mb,简称m;

一千兆字节叫做gb,简称g。

你用来存小电影的“32G的U盘”就是32个千兆字节!

你可能要问了,这跟32位和64位有什么关系?

32位计算机,所代表的意思是:每个地址用32个比特存储。

64位计算机,所代表的意思是:每个地址用64个比特存储。

所以说,32位计算机的最大运行内存为2^32比特

也就是4294967296bit

也就是4G。

所以说,32位的电脑,最大运行内存就是4G,就算插上8G内存条,也只能用4G的空间。如果有人卖给你8G的32位电脑…

恭喜你,你被坑了。

至于64位电脑,

2^64比特等于18446744073709551616比特

等于17179869184G,你一辈子暂时是用不完的。

说完了这些,我们回到刚刚的一句话:

所有的变量在计算机中都有唯一的地址

#include <iostream>
using namespace std;
int main()
{
    int a;//声明一个整型变量a
    int* p = &a;//声明一个指针变量p,赋值为a的地址
    cout << p << endl;//输出p并换行
    cout << &a;//输出a的地址
    return 0;
}

上面用到了两个新的运算符:

int*&**

int*是一种类型,和int、char等等,本质上是一样的。

int*代表的意思是,声明一个指向整型变量的指针变量

举例:

int* p;

**&**是一个单目运算符。

**&**代表的意思是,取一个变量的地址。

举例:

int a;
cout << &a;

(这里我们用到了一个新的输出函数:cout

​ 它是一种输入输出流函数

​ 包含在头文件中)

那么,地址有什么用出呢?

首先,我们可以在函数里面利用地址进行除返回值外的输出。

int lalala(int x,int y){
    return 2*x;
}

上面这串代码,只能返回2x的值。如果我想要计算3y呢?

int lalala(int x,int* y){
    return 2*x;
    *y = 3 * (*y);
}

这样的话,y的值就变成3y的值。如果不利用地址来处理,那么y的值不会改变。

我们再来说一下数组。

数组是什么?就是一堆连续的空间,存储一堆相同类型的变量

我们利用角标来找到数组里的值。

比方说,我们可以这样声明一个整型数组:

int a[10000];

这个整型数组内能存储10000个数字,分别是a[0]、a[1]、a[2]…到a[9999]。

我们利用数组可以干很多很多事情:

for(int i = 1; i <= 100; i++){
    cin >> a[i];//输入100个数字,存储在数组里
}
for(int i = i; i <= 100 ;i++){
    //随便干点啥,比如排序,比如令a[i] *= 2
    //我这里就不写了
}
for(int i = 1; i <= 100; i++){
    cin >> a[i];//把排序好的数字输出
}

再打个比方

在我们工作的时候,数据大部分是由用户输入的,而不是事先给你的。

举个例子,你的用户给你一堆数据,要求你找出其中最大值。

首先,他给你一个数字,代表后续输入的数据个数

然后给你那些数据。

因为你不确定后续的数据到底有多少个,所以你没办法声明一堆诸如a1,a2,a10086的变量

但是如果你用数组,那么就会简单很多:

int a[MAXN];
int n;
cin >> n;
for(int i = 1; i <= n; i++){
	cin >> a[i];
}

哎?

为啥我这一节的标题是数组与指针?

他俩有啥关系?

别急,我们现在来说一说。

你刚刚已经学会了如何声明一个数组,

int a[1000];

你也学会了该如何输出数组中的某一位。

cout << a[20];

那么,你试没试过,a指的是什么呢?

来让我们试一试:

cout << a;

我们发现,它输出了一个奇奇怪怪的东西:

在笔者的电脑上,它是005FEC5C。

这就是数组的“首地址”

因为数组是一堆连续的空间

其实调用a[0]就是通过数组的首地址调用的

调用a[1]就是通过数组的下一个地址调用的

所以,在使用scanf函数的时候

&a[1]也可以写作a+1

这两个代表的意义完全相同,都是代表数组里面的第二个元素的地址

即a[1]的地址。

以此类推,第三个元素的地址就是&a[2],也就是a+2。

所以说啊

在printf函数中,输出的时候

a[10]也可以写作*(a+10)

不过记住加上括号,不然的话

*a+10,实际上是 *a + 10,也就是a[0]+10。

最近的文章

1.9 函数、递归与递推

函数的作用,一是为了减少代码量,二是为了便于调试。如果将所有代码的运行部分全部写在主函数中,那么调试的时候,只能一行一行调试然而如果封装了函数,可以只调试对应的函数。在编码中,能封装成函数,尽量封装成函数,这样会使你的思路更加清晰,逻辑更加简洁。返回值类型 函数名(形式参数类型 形式参数名){//可…

继续阅读
更早的文章

2.1 字符串与Ascii码

1.定义char a[100];2.初始化a[] = "hello";a[6] = {'h', 'e', 'l', 'l', 'o'};注:字符数组与其他字符数组不同,其最后一位为’\0’,即休止符。…

继续阅读