[C]数组和指针

它们很像vector和迭代器,C++程序尽量用vector和迭代器,除非有速度上的要求。

一、数组

数组是由类型名标识符维数组成的符合数据类型。

1.定义和初始化需要注意的地方

(1)数组长度是固定的,在编译之时就已确定好。

(2)数组的维数必须用值大于等于1的常量表达式定义(千万不能用变量),此常量表达式只能包含整型字面值常量、枚举常量、用常量表达式初始化的整型const对象。换句话说就是要满足两个条件

  • 为整型
  • 在编译时就可以知道确切值(以便编译器为数组分配空间)

(3)数组元素初始化时,若没有显式提供元素初值,则元素会被想普通变量一样初始化:

  • 函数体外定义的内置类型数组,元素初始化为0
  • 函数体内定义的内置类型数组,元素无初始化(注意,若只初始化部分元素,其后的元素此时也会被初试化为0)
  • 如果不是内置类型,则不管其在哪定义,自动调用其默认构造函数为其初始化;若该类无默认构造函数则会报错
#include<stdio.h>
int a[3]={5};//5 0 0
int b[3];//0 0 0
void main()
{
	int c[3]={5};//5 0 0
	int d[3];//随机
}

(4)数组不支持直接赋值和复制。

2.数组操作

(1)数组下标从0开始,类型为size_t,下标不可越界(编译器并不检查)

(2)数组名其值为指向该数组的指针值(即数组首元素按的地址值),但数组名还包含着数组的长度,元素的类型两方面的信息。作为函数参数传递之后,退化为指针,丢失数组长度信息。

二、指针

指针其值为一内存地址,包含了两方面的信息:

  • 指向的变量的地址
  • 指向的变量的类型

它通常与 解引用(*) 和 取地址(&) 操作符密切相关。

1.定义与初始化

int * a;
int* a;
int *a;//上面定义三种都可以

而且,对于内置类型而言,int型指针只能指向int型变量。同一行定义两个指针必须这样:int *p1,*p2;不可这样:int * p1,p2。所以说,定义的风格还是统一为第三种的好。

指针值为0表示他不指向任何对象,可以通过数值0在编译时值为0的const量以及NULL(cstdlib)来初始化,万不可通过整型变量来赋值,即使它可能为0

另外不可使用没有initialize的指针变量,指针由同类型的变量地址或另一指针初始化,但也会有特例:

double obj = 3.14;
void *Pd = &obj; //obj can be an object of any type



2.指针的操作

(1) 解引用生成左值

(2) 指针同引用的差别:这就像是指针常量与指针变量之间的差别,引用一旦定义必须初始化,之后它指向的对象就再不可改了。

(3) 指针可以指向指针

int ival = 1024;
int *pi = &ival;
int **ppi = &pi;//ppi points to a pointer to int
int *ppi = &pi;//error,can't convert to "int *" from "int **"

(4) 可以使用指针访问数组元素:在表达式中使用数组名时,该名字会自动转换为指向数组第一个元素的指针,这时要注意指针的算术操作,指针可以+(-) n(int 型),两指针可想减,结果为ptrdiff_t类型(cstddef头文件),使用下标访问数组时,实际上是使用下标访问指针

【例题】写出如下程序片段的输出。

int a[] = {1,2,3,4,5};
int *ptr = (int*)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));

【答案】2,5
【解析】a看做指向int类型的指针,类型为int*;&a可看作指向int[]类型的指针,类型为int[]*。(&a+1)指向的是第六个位置(其实不存在)。数组名a代表指向数组首元素的地址,&a代表整个数组的地址。

3.const和指针

(1)指向const对象的指针——常量指针

下面两种方式定义都可以,推荐第一种。

const int *ptr1;
int const *prt2;

ptr1,ptr2本身的值可以修改,所以在定义时可以不初始化,允许其被重新赋值而指向另一个对象。

另外注意,常量指针即“自以为指向const量”的指针:

  • 把一个const对象的地址赋给一个非const对象的指针会导致编译出错
  • 反过来,一个非const对象的地址赋给一个const对象的指针却是合法的,不可通过该指针修改基础对象,但可以通过别的方式修改。

(2)const指针——指针常量

其本身的值不能修改。

int a=0;
int *const pa=&a;

这意味着pa再也不能指向其他的对象。与任何const量一样,const指针也必须在定义时初始化。

4. 指针悬浮和内存泄露

(1) 指针悬浮,指针迷途或者 wild pointer 同指该指针指向的内存没有由程序分配到这个指针之上。

(2) 内存泄露通常是由系统将内存分配给指针,但之后指针却不再指向那个地方了。那块内存变成一块死内存了。 

三、补充

1. 关于字符数组和字符指针

定义方法不同:

char str[10];
char *ptr;

赋值方法不同:

char str[10];
str = "china";//error
strcpy(str, "china");//OK
char *ptr;
ptr = "china";

字符指针是变量,而数组名是地址常量。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值