您的位置:首页 > 其它

四、数组和指针

2016-10-05 16:24 134 查看

1. 为什么要引入数组?

数组是由一组具有相同数据类型的元素按照一定的规则组成的集合。用数组名表示存储区域的地址,用下标变量来标识数组中的每个元素。数组和指针有着密切的联系,任何能由数组下标完成的操作也都可以用指针来实现。用数组类型可以描述许多有意义的对象,便于处理同一性质的成批数据,如向量、矩阵等。

2. 一维数组(对应一个线性表)

一维数组的定义、存储和初始化

定义:数据类型 数组名[整型常量表达式];

存储:数组名/数组名[0]:存放该数组的首地址

初始化:在定义数组的同时,为数组元素赋初值。

初始化形式为:数据类型 数组名[整型常量表达式] = {常数1, 常数2, … , 常数n};

此时整型常量表达式可省略,数组长度由初值个数确定。

当整型常量表达式的值大于初始化值的个数时,其余的元素系统自动赋0。

数组元素的引用

下标方式:数组名[下标]

地址方式 :*(地址)

指针方式:*指针变量名

数组元素的基本操作

// 假设有定义:int  j, a
; N是已定义过的符号常量。
// 数组元素的输入
for (j=0; j<N; j++)
{
cin >> a[j];
}

// 数组元素的输出
for (j=0; j<N; j++)
{
cout << a[j] << " ";
}

// 数组元素的求和
sum=0;

for (j=0; j<N; j++)
{
sum += a[j];
}

// 求数组中的最小元素
min=a[0];                 //假设第一个元素值最小

for (j=1; j<N; j++)
{
if (a[j] < min)
{
min = a[j];
}
}

// 求数组中的最小元素下标
imin=0;                 //假设0为最小元素下标

for (j=1; j<N; j++)
{
if (a[j] < a[imin])
{
imin = j;
}
}


数组排序

选择法

冒泡法

插入法

快速排序法

3. 二维数组(相当于一个矩阵)

二维数组的定义和初始化

定义:数据类型 数组名[常量表达式1][常量表达式2];

初始化



二维数组的基本操作

任何维数的数组在内存中都是以线性表的形式连续存放的。

4. 字符数组

C/C++中没有专门的字符串变量,但提供了字符数组和字符指针来处理字符串的方法。

char型数组来表示“一串字符”,用格式字符%s使其以字符串的形式打印出来。
eg:printf("The str is: %s\n ")


字符数组的初始化

char str[6] = { 'h', 'e', 'l', 'l', 'o','\0' }; //如果一串字符没有以'\0'(即char型的数字0)结束,则printf或cout会一直尝试打印下去,直到遇到'\0'结束打印,'\0 之后的字符不会被打印出来'


char str[6] = "hello";  // 自动添加字符串结束符'\0',所以此时字符串的长度为6


字符数组的使用

字符串处理函数

5. 指针

为什么要引入指针?

指针可以有效的表示复杂的数据结构,方便的使用数组和字符串。在调用函数时可以获得一个以上的结果、能动态分配内存并直接处理内存单元,效率较高。

指针概念的引入

指针:是一个数据结构的首地址,它指向一个数据结构,是一个常量。

变量地址:每个变量在内存中存放都对应一段地址,第一个字节的地址就是变量的地址

指针变量:将存放地址的变量称为指针变量。

求地址运算符 &:&变量,取得变量的地址。

读/写内容运算符 * : *p 用于访问 p 指向的内存(读、写)

指针定义

是一种特殊类型的变量,用于存放另一变量的地址。

定义形式为:数据类型 * 标识符;

* 后面的标识符指针变量名(用于存放另一变量的地址), * 本身不是变量名的组成部分。

指针定义中的 * 与执行语句中的 * 的意义不同。执行语句中的 * 表示取内容,是一种间接访问变量的形式,指针定义中的 * 只表示其后面的标识符是一个指针变量。

指针定义中的数据类型不是指针本身的数据类型,而是指针所指的对象的数据类型

指针初始化:在定义的同时赋初值。



指针运算

赋值运算

// 假定有定义:int *p, a;
p = NULL;          // 指针的值为NULL(0) 表示不指向任何对象。
p = &a;              // p指向变量a。
p1 = &a; p2 = p1;   // 相同类型的指针变量可以相互赋值


p++ 和 p- -运算

自增或自减后p指向前一个或后一个元素,指针的值变为后一个变量或前一个变量的地址

p+n 和 p-n 运算(p为指针,n为整数)

p的值+n*sizeof(p指向的类型)
,p本身的值并没有变

int a = 5;
int* p = &a;
// 假设a的地址为1000,则:p的值为1000,p+3的值为:
1000 + 3*sizeof(int)=1000 + 3*4 = 1012
// 对于int* 来说,元素大小是4字节,所以后移三个元素、自然地址要加3*4


指针相减

两个类型相同的指针可以相减,结果为这两个地址差之间能够存放的数据个数(数据类型为指针所指的类型)。

int *p1, *p2;
假设p1指向1000,p2指向1008,
则p2-p1的值为:
(1008-1000) / sizeof(int) = 2


安全的使用指针

一个指针未赋值时,其值为随机值,此时指向了一个随机的内存地址,称为野指针

int* p = 0;
指针变量的值为0的指针,称为空指针

传递空指针:函数内部是有办法处理,判断一下就行
if (p)


传递野指针:函数内无法判断出来你是个野指针!

指针只允许指向两个地方:
指向变量、数组或者指向0


如果指向的目标的生命期已经终结(失效),则该指针也失效。

所以安全的使用指针要注意以下三点:

杜绝野指针

严防数组越界

使用指针前判断其指向的变量是否已经失效


6. 指针和数组

指针和一维数组

int a[3] = {10, 20, 30};
int *p;

// 当执行 p = a 或者 p = &a[0] 时,有如下等价关系成立:
p = a = &a[0]
p + i = a + i = &a[i]
*(p + i) = *(a + i) = a[i] = p[i]         // 可以把 p 当成数组来用

// p 与 a 的区别
// 两者同样是表示数组a的地址,在表现形式上可以互换,但它们本质不同,p是地址变量,而a是地址常量。


指针和二维数组

指针和字符串
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: