数组和指针的区别

合集下载

专题7 数组和指针的应用

专题7  数组和指针的应用

例1. 写出结果: main() { int *p1, a[10]={1,2,3,4,5,6,7,8,9,10} ; p1=a; printf(“%d ”,*p1); printf(“%d ”,*p1++); printf(“%d ”, *(p1+3)); printf(“%d ”,*++p1); printf(“%d ”,(*p1)++); printf(“%d ”,*p1--); printf(“%d ”,*p1); } 例2.若有定义语句:double x[5]={1.0,2.0,3.0,4.0,5.0},*p=x;则错误引用x数 组元素的是[08年9月] A)*p B)x[5] C)*(p+1) D)*x
[C] D) aa+1
(3)通过指针变量来表示数组中各元素的地址
可以定义一个指针变量来存放数组的指针或数组元素的指针,且指针变 量的基类型就是定义数组时的类型 int *p,a[10]; for(p=a,k=0; k<10;k++) p++; 将数据写入数组元素中几种方式: (1)for(p=a,k=0; k<10;k++) { scanf(“%d”,p); p++; } 进一步简化: (2)for(p=a,k=0; k<10;k++) scanf(“%d”,p++); 再进一步简化: (3)for(p=a,p-a<10; p++) scanf(“%d”,p); 以上三种写法是等价的,要掌握,能看懂。
2、 通过指针变量来引用一维数组元素 当指针变量指向数组中的某个数组元素时,可以通过“*”来访问其所 指向变量的数据。

指针和数组的关系

指针和数组的关系

指针和数组的关系
指针和数组是C语言中非常重要的概念,理解它们对于编写高效程序和避免常见错误
至关重要。

指针和数组的关系可以说是紧密相连的,因为数组名本质上就是一个指针。

在C语言中,数组名表示一个指向该数组第一个元素的指针,也就是数组的起始地址。

因此,如果我们定义一个数组a,那么&a和a是等价的,都表示数组第一个元素的地址。

例如,定义一个整型数组a:
int a[5] = {1, 2, 3, 4, 5};
我们可以通过数组名a访问数组中的元素。

例如,a[0]表示数组中的第一个元素,即1。

在C语言中,数组名本身是一个常量,即不能对其进行修改。

但是,我们可以使用指
针来访问数组中的元素,这就需要对指针进行加减运算来实现。

我们可以定义一个指向数组a的指针p,然后通过指针访问数组中的元素。

例如,*p
表示指针p所指向的数组的第一个元素,即1。

我们可以通过p++将指针p指向数组中的下一个元素,例如*p++表示指向数组中的第二个元素,即2。

因此,数组名和指针在C语言中是紧密相关的,数组名本质上就是一个指向数组第一
个元素的指针。

我们可以通过指针访问数组中的元素,并通过加减运算实现对数组的遍
历。

在实际编程中,使用指针可以提高程序的效率和灵活性。

使用指针可以避免对数组名
的重复引用,从而减少程序的存储空间和运行时间开销。

但是,指针操作也比较容易出现指针越界、空指针等错误,因此在使用指针时需特别
注意,避免出现不必要的错误。

数组和指针的区别

数组和指针的区别

数组和指针的区别数组和指针是C语言中非常重要的两个概念,它们在编写程序时起着极其重要的作用。

虽然它们在某种程度上非常相似,但它们之间也存在着很多的差异,下面我们就来分析一下它们的区别。

1. 定义方式数组是由一组具有相同类型的数据元素所组成的有序集合,每个元素具有相同的数据类型,可以通过下标在数组中访问对应的元素。

在C中,定义一个数组可以使用以下语句:```int arr[10];```这个语句定义了一个名为arr的整型数组,这个数组有10个元素。

而指针是一个变量,它存放了一个内存地址,这个地址与它存储的数据类型有关。

在C中,定义一个指针可以使用以下语句:```int *p;```这个语句定义了一个名为p的指针,这个指针指向一个整型变量。

2. 内存分配数组在定义时要求需要一定的内存空间来存储数组元素,因此在定义时就已经确定了内存空间的大小,且数组的大小不可改变。

例如,如果定义一个大小为10的数组,则它的大小就是10,无论实际使用时需要存储的元素个数是多少,数组的大小都不会改变。

而指针在定义时只需要分配一个指针变量所需的内存空间,该指针可以在程序运行时动态地分配内存,因此指针所指向的内存空间大小不确定,需要在运行时根据需要动态地分配或释放空间。

3. 访问方式在数组中,可以通过数组的下标来访问数组中具体的元素,下标从0开始,最大下标为数组大小减1。

例如,访问arr数组中的第三个元素可以写成:arr[2]。

而对于指针,可以通过指针变量所指向的地址来访问该地址所对应的值。

例如,访问p指针所指向地址上的整型变量可以写成:*p。

4. 传递方式在函数调用时,数组可以通过值传递或指针传递来传递数组的值。

如果数组作为参数传递给函数时,实际上传递的是该数组的地址,即使数组非常大,也不会导致栈溢出。

而对于指针,只能通过指针传递方式来传递指针变量的值,在函数内部可以通过指针来修改该指针所指向的地址所存储的值,因此指针可以用来传递地址或修改变量的值。

用指针访问数组的方法

用指针访问数组的方法

用指针访问数组的方法一、指针与数组的关系。

1.1 指针就像是数组的导航员。

数组在内存里是一块连续的空间,就像住在公寓里的一排房间。

而指针呢,就好比是房间的钥匙或者说是指向这些房间的路标。

它能准确地找到数组里的每个元素,这就跟你拿着钥匙能打开对应的房间门一样。

咱们可以把数组想象成一群小伙伴排着队,指针就可以指出哪个是排头,哪个是排尾,还能找到中间的小伙伴。

1.2 从本质上来说,数组名其实就是一个指针常量。

这就像是一个固定的地址标签,它指向数组的第一个元素。

就好比你家的门牌号,永远指着你家这个“元素”所在的位置。

而且,这个指针常量是不能被修改的,就像你不能随便更改你家的门牌号一样。

二、用指针访问数组元素。

2.1 简单的访问方式。

咱们先定义一个数组,比如说int arr[5] = {1, 2, 3, 4, 5};再定义一个指针,int p = arr; 这里的arr就相当于把数组的首地址给了指针p。

现在如果我们想访问数组的第一个元素,就可以用p,这就像是通过钥匙打开了第一个房间。

如果我们想访问第二个元素呢,那就可以让指针p指向下一个元素,也就是p++,然后再用p来获取这个元素的值。

这就好像你沿着走廊走到下一个房间,再用钥匙打开门看看里面有啥。

2.2 灵活的遍历。

通过指针来遍历数组那是相当方便的。

我们可以写一个简单的循环,像这样:for (int p = arr; p < arr + 5; p++) { printf("%d ", p); }。

这个循环就像是一个小机器人,从数组的开头沿着指针这个“导航路线”一直走到结尾,把每个房间里的东西(元素的值)都展示出来。

这就好比是你沿着一排房间一个一个地查看里面的情况,一个都不落下。

2.3 指针运算的妙处。

指针的运算在访问数组的时候可是很有讲究的。

比如说,p + 2,这里可不是简单的数学加法,它实际上是让指针向后移动两个元素的位置。

这就像是你一下子跳过两个房间,直接到第三个房间的门口。

字符串指针与字符数组的区别

字符串指针与字符数组的区别

字符串指针与字符数组的区别(转载)用字符数组和字符指针变量都可实现字符串的存储和运算。

但是两者是有区别的。

在使用时应注意以下几个问题:1. 字符串指针变量本身是一个变量,用于存放字符串的首地址。

而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以‘\0’作为串的结束。

字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。

2. 对字符串指针方式char *ps="C Language";可以写为:char *ps;ps="C Language";而对数组方式:static char st[]={"C Language"};不能写为:char st[20];st={"C Language"};而只能对字符数组的各元素逐个赋值。

从以上几点可以看出字符串指针变量与字符数组在使用时的区别,同时也可看出使用指针变量更加方便。

当一个指针变量在未取得确定地址前使用是危险的,容易引起错误。

一个错误的例子,如下:char *name;scanf("%s",name);printf("%s",name);有的编译器虽然也能通过,但这是错误的,因为是个指针,定义时指向不可用的地址。

解决这个问题有两种方法:用数组的方法或给字符针针分配内存空间的方法。

数组的方法:char name[20];scanf("%s",name);printf("%s",name);给字符针针分配内存空间的办法:char *name;name=(char*)malloc(50);//此时name已经指向一个刚刚分配的地址空间。

scanf("%s",name);printf("%s",name);但是对指针变量直接赋值是可以的。

因为C系统对指针变量赋值时要给以确定的地址。

理解C语言(一)数组、函数与指针

理解C语言(一)数组、函数与指针

理解C语⾔(⼀)数组、函数与指针1 指针⼀般地,计算机内存的每个位置都由⼀个地址标识,在C语⾔中我们⽤指针表⽰内存地址。

指针变量的值实际上就是内存地址,⽽指针变量所指向的内容则是该内存地址存储的内容,这是通过解引⽤指针获得。

声明⼀个指针变量并不会⾃动分配任何内存。

在对指针进⾏间接访问前,指针必须初始化: 要么指向它现有的内存,要么给它分配动态内存。

对未初始化的指针变量执⾏解引⽤操作是⾮法的,⽽且这种错误常常难以检测,其结果往往是⼀个不相关的值被修改,并且这种错误很难调试,因⽽我们需要明确强调: 未初始化的指针是⽆效的,直到该指针赋值后,才可使⽤它。

 int *a;*a=12; //只是声明了变量a,但从未对它初始化,因⽽我们没办法预测值12将存储在什么地⽅int *d=0; //这是可以的,0可以视作为零值int b=12;int *c=&b;另外C标准定义了NULL指针,它作为⼀个特殊的指针常量,表⽰不指向任何位置,因⽽对⼀个NULL指针进⾏解引⽤操作同样也是⾮法的。

因⽽在对指针进⾏解引⽤操作的所有情形前,如常规赋值、指针作为函数的参数,⾸先必须检查指针的合法性- ⾮NULL指针。

解引⽤NULL指针操作的后果因编译器⽽异,两个常见的后果分别是返回置0的值及终⽌程序。

总结下来,不论你的机器对解引⽤NULL指针这种⾏为作何反应,对所有的指针变量进⾏显式的初始化是种好做法。

如果知道指针被初始化为什么地址,就该把它初始化为该地址,否则初始化为NULL在所有指针解引⽤操作前都要对其进⾏合法性检查,判断是否为NULL指针,这是⼀种良好安全的编程风格1.1 指针运算基础在指针值上可以进⾏有限的算术运算和关系运算。

合法的运算具体包括以下⼏种: 指针与整数的加减(包括指针的⾃增和⾃减)、同类型指针间的⽐较、同类型的指针相减。

例如⼀个指针加上或减去⼀个整型值,⽐较两指针是否相等或不相等,但是这两种运算只有作⽤于同⼀个数组中才可以预测。

数组与指针

数组与指针

此外,还可通过算术元运算对指针进行移动, 此外,还可通过算术元运算对指针进行移动,来达到引用 其他数组元素的目的。 其他数组元素的目的。 a[0] p p &a[0] *p a[0] a[1] p+1 p+1 &a[1] *(p+1) a[1] a[2] P+2 p+2 &a[2] *(p+2) a[2] a[3] P+3 p+3 &a[3] *(p+3) a[3] a[4] p+4 p+4 &a[4] *(p+4) a[4]
a[0] a[1] a[2] a[3] a[4]
a
a a+1 a+2 a+3 a+4
a a+1 a+2 a+3 a+4
&a[0] &a[1] &a[2] &a[3] &a[4]
*a *(a+1) *(a+2) *(a+3) *(a+4)
a[0] a[1] a[2] a[3] a[4]
例3: main() { int a[5],*p,i; for(i=0;i<5;i++) scanf(“%d”,a+i); for(i=0;i<5;i++) printf(“%d”,*(a+i)); }
a[1] a[1][0] a[1][1] a[1][2]
此处, 的值与 的值与a[0]的值相同,但是基类型不同。a是二级 的值相同, 此处,a的值与 的值相同 但是基类型不同。 是二级 指针, 是一级指针。 指针,a[0]是一级指针。 是一级指针 a &a[0][0] a[0] 因此,以下赋值语句是错误的: 因此,以下赋值语句是错误的:p=a; a &a[0] a+1 &a[1] a+i &a[i] *(a+i) a[i]

字符串指针和字符数组,静态全局、静态局部、全局和局部变量区别,字符串常量和字符串变量,程序的内存分配

字符串指针和字符数组,静态全局、静态局部、全局和局部变量区别,字符串常量和字符串变量,程序的内存分配

最近工作之余,发现了两个自己在C语言学习中的难点,一个是字符串指针和字符数组的区别,一个就是静态全局变量、静态局部变量、全局变量和局部变量的区别,在网上查了不少资料,收获良多,现在与大家分享,有错误的地方请大家指正!以下程序用VC++6.0调试先说说字符串指针和字符数组的区别1.相同点:/* 用字符数组实现字符串操作*/main( ){char str[]="Welcome to study C !";int i;printf("%s\n",str);for (i=0;i<=7;i++)printf("%c",str[i]); //用*(str+i)也行printf("\n");}/* 用字符指针实现字符串操作*/main(){char *str="Welcome to study C !";int i;printf("%s\n",str);for(i=0;i<=7;i++)printf("%c",*(str+i)); //用str[i]也行printf("\n");}2.不同点:a)赋值方式不同,字符数组只能对各个元素分别赋值,而字符指针只需赋给字符串的首地址就可以了。

如: char *str;str="Welcome to study C !";以下对字符数组的赋值是错误的:char str[80];str[ ]="Welcome to study C !";b)字符指针指向字符串,"hello"是一个字符串常量,与之相关联的内存空间位于内存的只读部分,如:char ch[] = "china\n";char *p;char *pp = "CHINA\n";p = ch;*(p+2) = 'h';//就是可以的*(pp+2) = 'h';//此处在编译时不会出错,在执行的时候会出错c) 函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型,对于void func (char sa[100],int ia[20],char *p),则sa的类型为char*,而不是char[100]类型下面介绍一下字符串常量和字符串变量:1.字符串常量:a)定义:是一对双引号括起来的字符序列b)字符串包含的字符个数:不包括系统自动赋的’\0’,转义字符算1个c)所占的字节数:字符串所包含的字符个数加1d)长度:从第一个字符到第一个’\0’之间的字符个数,哪怕’\0’就在原字符串中e)无论字符串常量还是字符串变量,空字符串可以存在””,而空字符是错误的’’2.字符串变量:a)C语言本身没有设置一种类型来定义字符串变量,字符串的存储完全依赖于字符数组,但字符数组又不等于是字符串变量,例如:Char str[] = {‘a’,’b’,’c’,’\0’};是str[4],是字符串Char str[] = {‘a’,’b’,’c’};是str[3],是字符数组Char str[7] = “string!”;可能破坏其他数据b)在scanf,printf,gets,puts中的str不用写成str[10],只能写成str下面介绍下静态全局变量,静态局部变量,全局变量,局部变量的区别1.从作用域看:全局变量具有全局作用域。

CC++常见问题汇总

CC++常见问题汇总

CC++常见问题汇总问题1、数组和指针的区别数组名不可以作为左值char * p1 = "Hello World" ; //分配字符串常量,然后赋给 p1 ,⼀个指针型变量,是左值char p2[ 20] = "Hello World" ; //分配⼀个数组,然后初始化为字符串,相当于⼀个常量,类型为数组,不是左值*p1 = 'h' ; //p1可以指向别的地⽅,但hello world不能更改p2[ 0] = 'h' ; //p2不能指向别的地⽅,但hello world可以更改si z eo f运算sizeof(指针变量p1)是编译器分配给指针(也就是⼀个地址)的内存空间。

sizeof(数组指针常量p2)是整个数组占⽤空间的⼤⼩。

但当数组作为函数参数进⾏传递时,数组就⾃动退化为同类型的指针。

取地址&运算对数组名取地址&运算,得到的还是数组第⼀个元素的地址对指针取地址&运算,得到的是指针所在的地址,也就是指向这个指针的指针。

因此main函数的参数char *argv[],也可以写成char **argv。

参考问题2、指针数组、数组指针与⼆维数组剖析定义指针数组:⾸先它是⼀个数组,数组的元素都是指针,数组占多少个字节由数组本⾝决定。

它是“储存指针的数组”的简称。

数组指针:⾸先它是⼀个指针,它指向⼀个数组。

在32 位系统下永远是占4 个字节,⾄于它指向的数组占多少字节,不知道。

它是“指向数组的指针”的简称。

实例区分int *p1[10]; //p1 是数组名,其包含10 个指向int 类型数据的指针,即指针数组int (*p2)[10]; //p2 是⼀个指针,它指向⼀个包含10 个int 类型数据的数组,即数组指针cout<<sizeof(a)<<""<<sizeof(b); //4 40实例分析符号优先级:()> [ ] > *p1 先与“[]”结合,构成⼀个数组的定义,数组名为p1,int *修饰的是数组的内容,即数组的每个元素。

C语言中指针和数组区别的分析

C语言中指针和数组区别的分析
之 间 的区别 。 数 组和指 针的 不 同之处


我 们来 看 以下代码 :
i e . fl 1c
假 设 编译 器 符 号 表 给 的一 个 地 址 是 2 0 0 0程 序 运 行 时 , 3的值 , 它 与 2 0 取 将 0 0相 加 , 得 ( 0 0 3 的内 取 20 + ) 容 。 这里 , 个符 号 的地址在 编译 时可 知 。 在 每 因此 。 如果 编译 器需 要一 个地 址来 执行 某个 操作 得 花 .它就 可 以
ca ] hr I s
ad n c a s hr :
作 符 , 像减号 表示 一个 减法 运算 符一 样 。 就 取下 标操 作 符就 像 取一 个 整数 和 一个 指 向类 型 x 的指 针 . 产生 所 a e e u v l n ‘・・ r q i ae t。・ ・ 意思 是 : 为 函数 参数定 义 的形 式参 数 ,h rs 和 的结 果类 型是 X.一 个 在表达 式 中的数组 名 于是 就成 作 c a 口 了指 针 。 c a s h r 是一样 的 在 表达 式 中 . 指针 和 数组 是 可 以相互 替 换 的 , 因为 在 函数 形参 定 义这 个特 殊 的情 况 下 .编 译 器必 须 把 数 组形 式 改 写 成指 向数 组 第 一个 元 素 的指 针形 式 。 他们 在编译 器里 的最 终形 式 都是 指针 。并 且 都可 以进 在这里, 编译 器 只向 函数传 递数 组 的地 址 , 而不 是整 个 行取 下标操 作 编译 器 可 以 自动 把 下标值 的 步长 调整 到数 组 的大小 .如 : n l g型数 据 的长度 是 4个 字节 . o 那 数 组 的拷 贝 。 因此 以 下几种 :
对于 C语 言 编程新 手 来 说 . 常认 为 n 经 数组 和 指针 在 C语 言 中 。 我把 地 址形 象 地称 为 ” 针 ” 把存 放 指 . 是 相 同的 ” 。其 实这 种 说法 是不 完全 正 确 的 , 们 是有 地址 的变量 称 为指针 变 量 .通 常 我们 把指 针变 量 简称 他 区别 的。A SC标 准 6 4 N I . 2里 建议 : 5 为 指针 。 以指针 里存 放 的是 数据 的地址 。 所 而数 组里 存 注意下列 声 明 的区别 : 放 的是数 据 的值 。 e t r n x xe n i t : 2数组 和 指针 的访 问方 式不 同 . 数 组 采用 的是 直接 访 问方 式 .而指 针 采用 的是 间 etr t [ xeni ] ny; 第 一条 语 句声 明 x是一 个 it 的指 针 . 二条 语 接 访 问方 式 。 n型 第 句声 明 Y是 it . 组 长 度 尚未 确 定 . n型 数 其存 储 在 别 处 如 : h r 【】 ” hn ” c a 6= C ia; a c a3; = 【】

详解C++数组和数组名问题(指针、解引用)

详解C++数组和数组名问题(指针、解引用)

详解C++数组和数组名问题(指针、解引⽤)⽬录⼀、指针1.1指针变量和普通变量的区别1.2为什么需要指针1.3指针使⽤三部曲⼆、整形、浮点型数组2.1数组名其实是特殊的指针2.2理解复杂的数组的声明2.3数组名a、数组名取地址&a、数组⾸元素地址&a[0]、指向数组⾸元素的指针*p2.4对数组名以及取值符&的理解三、字符数组数组名⼀、指针1.1 指针变量和普通变量的区别指针:指针的实质就是个变量,它跟普通变量没有任何本质区别。

指针完整的应该叫指针变量,简称为指针。

是指向的意思。

指针本⾝是⼀个对象,同时指针⽆需在定义的时候赋值。

1.2 为什么需要指针指针的出现是为了实现间接访问。

在汇编中都有间接访问,其实就是CPU的寻址⽅式中的间接上。

间接访问(CPU的间接寻址)是CPU设计时决定的,这个决定了汇编语⾔必须能够实现问接寻⼜决定了汇编之上的C语⾔也必须实现简介寻址。

1.3 指针使⽤三部曲三部曲:定义指针变量、关联指针变量、解引⽤(1)当我们int *p定义⼀个指针变量p时,因为p是局部变量,所以也道循C语⾔局部变量的⼀般规律(定义局部变量并且未初始化,则值是随机的),所以此时p变量中存储的是⼀个随机的数字。

(2)此时如果我们解引⽤p,则相当于我们访问了这个随机数字为地址的内存空间。

那这个空间到底能不能访问不知道(也许⾏也许不⾏),所以如果直接定义指针变量未绑定有效地址就去解引⽤⼏平必死⽆疑。

(3)定义⼀个指针变量,不经绑定有效地址就去解引⽤,就好象拿⼀个上了镗的枪随意转了⼏圈然后开了枪。

(4)指针绑定的意义就在于让指针指向⼀个可以访问、应该访问的地⽅(就好象拿着枪瞄准且标的过程⼀样),指针的解引⽤是为了间接访问⽬标变量(就好象开枪是为了打中⽬标⼀样)int val = 43;int * p = &val; // &在右值为取值符cout << *p << endl;//输出43⼆、整形、浮点型数组前⾔在很多⽤到数组名字的地⽅,编译器都会⾃动地将其替换为⼀个指向该数组⾸元素的指针。

指针与数组

指针与数组

3.通过一个行指针变量引用二维数组的元素
定义一个由m个元素组成的一维数组的指 针变量的一般形式:
类型标识符 (*指针变量名)[m];
注意:*p两侧的圆括号不可缺少。 例如:假若有语句 int a[2][3], (*p)[3]; p=a;
则:⑴ p是一个指向由3个整型元素组成的一 维数 组的指针变量。
方法ain() { int a[10]={54,65,8,2,3,56,8,21,57,98},i;
for(printf("\n"),i=0;i<10;i++) printf("%4d",*(a+i)); }
方法三:用指针变量指向数组元素
main() { int a[10]={54,65,8,2,3,56,8,21,57,98},*p,i;
⑵ p指向a数组,p+1指向数组a的下一行首地 址,a和p的基类型相同,则a数组中任意元 素a[i][j]还可以如下表示: *(p[i]+j) 、*(*(p+i)+j) 、(*(p+i))[j] 、p[i][j]
例:使用行指针变量访问数组元素。
main() {
float fa[5][10], (*pf)[10]=fa; int i,j; for(i=0; i<5; i++)
C语言程序设计
指针与数组
1.1 一维数组的指针
数组的指针 :是数组的起始地址。
数组元素的指针 :是数组元素的地址。 当指针变量指向数组或数组元素时,它就是指 向数组的指针变量。
C规定: ⑴数组名代表数组的首地址(起始地址),
也就是第一个元素的地址。
⑵当指针变量p指向数组时,p+1指向数组 的下一个元素。假设一个整型元素占两 个字节,p+1是使p的地址加2个字节。

数组和指针

数组和指针

● 数组:数组是具有一定顺序关系的若干对象的集合体,组成数组的对象称为该数组的元素。

▲ 每个元素有n个下标的数组称为n维数组。

▲ a[100]:下标从0开始,到99止,不能为100。

▲ a[i][j]:i为行标,j为下标。

● 数组的声明:数组类型数组名[表达式1][表达式2]……● 数组的使用:数组类型数组名[表达式1][表达式2]……● 数组的存储:数组元素在内存中是顺序、连续存储的。

● 数组的初始化:就是在声明数组时给部分或全部元素赋初值。

▲ int a[3]={1,2,3}; 等价于 int[]{1,2,3};▲ int a[5]={1,2,3}; //部分初始化,必须连续,不能间隔赋初值▲ int a[2][3]={1,2,3,4,5,6}; 等价于 int a[][3]={1,2,3,4,5,6} //给出全部的初值时,行标可省▲ int a[2][3]={{1,2},{3,4},{5,6}};● 数组作为函数参数▲ 使用数组名传递数据时,传递的是地址▲ 使用数组名做函数的参数,则实参和形参都应该是数组名,且类型要相同▲ 对形参数组的修改,也就是对实参数组的修改▲ int ss(int a[][4],int bb) 调用:ss(b,x); //b是数组,x传递的是第一维的维数● 对象数组▲ 声明:类名数组名[下标表达式]▲ 引用:数组名[下标].成员名▲ 当一个数组中的元素对象被删除时,系统会调用析构函数来完成扫尾工作。

● 指针:是对地址直接操作的手段。

动态内存分配和管理也离不开指针● 指针类型:用来存放内存单元地址的变量类型,就是指针类型。

● 指针变量的声明:数据类型 *标识符;● 与地址相关的运算——"*"和"&"▲ "*"称为指针运算符(也称解析(dereference)),表示获取指针所指向的变量的值,是一元操作符。

C语言指针用法详解

C语言指针用法详解

C语言指针用法详解C语言指针用法详解指针可以说是集C语言精华之所在,一个C语言达人怎么可以不会指针呢。

下面店铺给大家介绍C语言指针用法,欢迎阅读!C语言指针用法详解(1)关于指针与数组的存储a、指针和数组在内存中的存储形式数组p[N]创建时,对应着内存中一个数组空间的分配,其地址和容量在数组生命周期内一般不可改变。

数组名p本身是一个常量,即分配数组空间的地址值,这个值在编译时会替换成一个常数,在运行时没有任何内存空间来存储这个值,它和数组长度一起存在于代码中(应该是符号表中),在链接时已经制定好了;而指针*p创建时,对应内存中这个指针变量的空间分配,至于这个空间内填什么值即这个指针变量的值是多少,要看它在程序中被如何初始化,这也决定了指针指向哪一块内存地址。

b、指针和数组的赋值与初始化根据上文,一般情况下,数组的地址不能修改,内容可以修改;而指针的内容可以修改,指针指向的内容也可以修改,但这之前要为指针初始化。

如:int p[5];p=p+1; 是不允许的而p[0]=1; 是可以的;//int *p;p=p+1; 是允许的p[0]=1; 是不允许的,因为指针没有初始化;//int i;int *p=&i;p[0]=1; 是允许的;对于字符指针还有比较特殊的情况。

如:char * p="abc";p[0]='d'; 是不允许的为什么初始化了的字符指针不能改变其指向的内容呢?这是因为p 指向的是“常量”字符串,字符串"abc"实际是存储在程序的静态存储区的,因此内容不能改变。

这里常量字符串的地址确定在先,将指针指向其在后。

而char p[]="abc";p[0]='d'; 是允许的这是因为,这个初始化实际上是把常量直接赋值给数组,即写到为数组分配的内存空间。

这里数组内存分配在先,赋值在后。

(2)关于一些表达式的含义char *p, **p, ***p;char p[],p[][],p[][][];char *p[],*p[][],**p[],**p[][],*(*p)[],(**p)[],(**p)[][];能清晰地知道以上表达式的含义吗?(知道的去死!)第一组:char *p, **p, ***p;分别为char指针;char*指针,即指向char*类型数据地址的指针;char**指针,即指向char**类型数据的指针;他们都是占4字节空间的指针。

数组表示法和指针表示法

数组表示法和指针表示法

数组表示法和指针表示法是在编程中常用的两种表示数据结构的方式。

1. 数组表示法:数组是一种线性数据结构,它由相同类型的元素按照一定顺序排列而成。

在数组表示法中,我们可以通过数组下标来访问数组中的元素。

数组的下标通常从0开始,依次递增。

例如,如果有一个整型数组 `arr`,我们可以通过 `arr[0]`、
`arr[1]`、`arr[2]` 等方式来访问数组中的元素。

2. 指针表示法:指针是一种变量,其值为另一个变量的内存地址。

在指针表示法中,我们可以使用指针来访问内存中存储的数据。

通过指针,我们可以获取变量的地址,并且可以通过解引用操作符 `*` 来访问该地址处存储的值。

例如,如果有一个指向整型变量的指针 `ptr`,我们可以通过 `*ptr` 来获取该整型变量的值。

在实际编程中,数组表示法和指针表示法经常结合使用,特别是在涉及数组操作和内存管理的情况下。

指针可以用来遍历数组、访问动态分配的内存以及实现复杂的数据结构,从而提高程序的灵活性和效率。

指针与数组

指针与数组

#include <stdio.h>
int main()
{ int a[6],i,s,*p;
printf("Please input data:\n");
for(i=0; i<6; i++ )
scanf("%d", &a[i] );
s=0;
for(p=a; p<a+6; p++) s+=*p ;
printf(“s=%d\n”,s);
8
指针与数组
❖指针运算:
指针类型的数据,除了间接引运算、赋值运算 p 2000
等操作外,当指针指向数组时,指针可以做
加减整数、指针相减及指针比较运算。
▪ 1.指针与整数的加、减运算
• 如果指针p是指向数组中的某个元素,加
p+3 2012
上整数n后,新指针p+n指向后续的第n个
a数组
1 2 3 4 5
a[0] a[1] a[2] a[3]
a[4]
元素。
a[5]
▪ 2.指针相减运算
a[6]
• 两个指向同个数组的同类型指针作相减运
a[7]
算,其绝对值表示它们之间相隔的元素数 目。
p+92036
a[8] a[9]
▪ 3.指针之间作关系运算
• 两个相同类型指针可作关系运算比较指针
大小。例8.5程序循环控制是通过 p<a+6
– 行指针a+2,转化为元素指针*(a+2),指向第3行第一个元素,即 a[2][0]。
– 行指针a+i,转化为元素指针*(a+i)+j,指向第i+1行第j+1一个元素, 即a[i][j]。

数组指针和指针数组的区别

数组指针和指针数组的区别

数组指针和指针数组的区别数组指针(也称⾏指针)定义 int (*p)[n];()优先级⾼,⾸先说明p是⼀个指针,指向⼀个整型的⼀维数组,这个⼀维数组的长度是n,也可以说是p的步长。

也就是说执⾏p+1时,p要跨过n个整型数据的长度。

如要将⼆维数组赋给⼀指针,应这样赋值:int a[3][4];int (*p)[4]; //该语句是定义⼀个数组指针,指向含4个元素的⼀维数组。

p=a; //将该⼆维数组的⾸地址赋给p,也就是a[0]或&a[0][0]p++; //该语句执⾏过后,也就是p=p+1;p跨过⾏a[0][]指向了⾏a[1][]所以数组指针也称指向⼀维数组的指针,亦称⾏指针。

指针数组定义 int *p[n];[]优先级⾼,先与p结合成为⼀个数组,再由int*说明这是⼀个整型指针数组,它有n个指针类型的数组元素。

这⾥执⾏p+1时,则p指向下⼀个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表⽰,只存在p[0]、p[1]、p[2]...p[n-1],⽽且它们分别是指针变量可以⽤来存放变量地址。

但可以这样 *p=a; 这⾥*p表⽰指针数组第⼀个元素的值,a的⾸地址的值。

如要将⼆维数组赋给⼀指针数组:int *p[3];int a[3][4];p++; //该语句表⽰p数组指向下⼀个数组元素。

注:此数组每⼀个元素都是⼀个指针for(i=0;i<3;i++)p[i]=a[i]这⾥int *p[3] 表⽰⼀个⼀维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]所以要分别赋值。

这样两者的区别就豁然开朗了,数组指针只是⼀个指针变量,似乎是C语⾔⾥专门⽤来指向⼆维数组的,它占有内存中⼀个指针的存储空间。

指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。

还需要说明的⼀点就是,同时⽤来指向⼆维数组时,其引⽤和⽤数组名引⽤都是⼀样的。

⽐如要表⽰数组中i⾏j列⼀个元素:*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]优先级:()>[]>*=========================================================================⼀、指针数组和数组指针的内存布局初学者总是分不出指针数组与数组指针的区别。

第5章 数组与指针

第5章 数组与指针

也可以用函数strcpy( )实现:
char amounts[6]=”hello”; char customer[6]; strcpy(customer, amounts); /*可以将amounts中的数据复制给 customer*/
(3)strcat()——字符串的连接 该函数是将一个字符串连接到另一个字符串的后面 ,得到一个新的字符串。如要将字符串customer连接到 字符串amounts的后面,可以采用下列语句:
float temp; for(int i=0;i<29;i++) { for(int j=i+1;j<30;j++) { if (cj[i]<cj[j]) { temp = cj[i]; cj[i] = cj[j]; cj[j] = temp; } } } }
//排序
void display( ) { for(int j = 0;j< 30; ++j) { cout << cj[j]<< endl; } } }; int main( ) { students C1; C1.sortData( ); C1.display( ); }
例如:要记录学生的姓名,该如何定义数组?
分析:由于学生的姓名是属于字符串,所以要定义一个字符串数组,如 果每个学生的姓名长度在20个字符以内,则可以定义该数组的长度为21 。
char name[21];
• 5.1.4字符串的主要操作
1.字符串的输入和输出 字符串的输入和输出与一般变量的输入与输出类似, 用cin和cout实现。
第5章 数组与指针
本章学习要点
• 1. 掌握一维数组的定义、赋初值以及简单应用; • 2. 掌握一维字符数组和字符串之间的关系,了解字符 串的常用操作; • 3. 掌握二维数组的定义、赋初值,了解其应用; • 4. 掌握指针的定义和运算; • 5. 掌握指针与一维数组、字符串的关系; • 6. 掌握动态内存管理的方法; • 7.掌握别名引用和指针引用。

CC++——二维数组与指针、指针数组、数组指针(行指针)、二级指针的用法

CC++——二维数组与指针、指针数组、数组指针(行指针)、二级指针的用法

CC++——⼆维数组与指针、指针数组、数组指针(⾏指针)、⼆级指针的⽤法1. ⼆维数组和指针要⽤指针处理⼆维数组,⾸先要解决从存储的⾓度对⼆维数组的认识问题。

我们知道,⼀个⼆维数组在计算机中存储时,是按照先⾏后列的顺序依次存储的,当把每⼀⾏看作⼀个整体,即视为⼀个⼤的数组元素时,这个存储的⼆维数组也就变成了⼀个⼀维数组了。

⽽每个⼤数组元素对应⼆维数组的⼀⾏,我们就称之为⾏数组元素,显然每个⾏数组元素都是⼀个⼀维数组下⾯我们讨论指针和⼆维数组元素的对应关系,清楚了⼆者之间的关系,就能⽤指针处理⼆维数组了。

设p是指向⼆维数组a[m][n]的指针变量,则有:int* p=a[0];//此时P是指向⼀维数组的指针。

P++后,p指向 a[0][1]。

如果定义int (*p1)[n];p1=a;p1++后,p1指向a[1][0];则p+j将指向a[0]数组中的元素a[0][j]。

由于a[0]、a[1]┅a[M-1]等各个⾏数组依次连续存储,则对于a数组中的任⼀元素a[i][j],指针的⼀般形式如下:p+i*N+j 相应的如果⽤p1来表⽰,则为*(p1+i)+j元素a[i][j]相应的指针表⽰为:*( p+i*N+j) 相应的如果⽤p1来表⽰,则为*(*(p1+i)+j)同样,a[i][j]也可使⽤指针下标法表⽰,如下:p[i*N+j]例如,有如下定义:int a[3][4]={{10,20,30,40,},{50,60,70,80},{90,91,92,93}};则数组a有3个元素,分别为a[0]、a[1]、a[2]。

⽽每个元素都是⼀个⼀维数组,各包含4个元素,如a[1]的4个元素是a[1][0]、a[1][1]、a[1]2]、a[1][3]。

若有:int *p=a[0];则数组a的元素a[1][2]对应的指针为:p+1*4+2元素a[1][2]也就可以表⽰为:*( p+1*4+2)⽤下标表⽰法,a[1][2]表⽰为:p[1*4+2]特别说明:对上述⼆维数组a,虽然a[0]、a都是数组⾸地址,但⼆者指向的对象不同,a[0]是⼀维数组的名字,它指向的是a[0]数组的⾸元素,对其进⾏“*”运算,得到的是⼀个数组元素值,即a[0]数组⾸元素值,因此,*a[0]与a[0][0]是同⼀个值;⽽a是⼀个⼆维数组的名字,它指向的是它所属元素的⾸元素,它的每⼀个元素都是⼀个⾏数组,因此,它的指针移动单位是“⾏”,所以a+i指向的是第i个⾏数组,即指向a[i]。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算出数组的容量(字 节数)。(包括最后面的'\0')。指针p指向a, 但是sizeof(p)的值却是4。这是因为sizeof(p)得 到的是一个指针变量的字节数,相当于 sizeof(char*),而不是p所指的内存容量 siziof(char[6])。C++/C不能知道指针所指的内 存容量。 值得注意的是,当数组作为函数的参数进 行传递时,数组就自动退化为同类型的指针。 那么不论数组a的容量是多少,sizeof(a)始终等 于sizeof(char *)。

char str[7]=”ksarea”; char *pstr=str; cout<< str[3]<<pstr[3]<<endl; 其中str[3]和pstr[3]返回的都是字符‟r„,但是编译 器产生的执行代码却不一样。对于str[3],执行代 码是从str开始,向后移动三个字节,然后取出其中 的字符;而对于pstr[3],执行代码是从pstr中取出 地址,然后在其上加3,然后取出对应内存中的字 符。当然,如果pstr是指向int型的指针,那么 pstr[3]的处理过程是从pstr中取出地址,然后在其 上加上3*sizeof(int),最后取出对应内存中的字符, 其他的数据类型一次类推。

a. 将数组名直接赋值给指针,数组名转换为指 向数组的首单元的常量指针。 b.直接将数组名作为指针形参的时候,数组名 则转换为指向数组的首单元的常量指针进行传 递,如下程序2: void fun(char str[]) 。。。 char str1[5]; fun(str1);
数组名作为函数形参进行传递时,在子函数体
内,它已经不再是一个指针常量,而是变成一 个真正的指针,可以进行增减等操作,可以被 修改。所以程序2中子程序第一条语句输出的 sizeof(str)的值为4.
既然数组名可以被看作指针常量,而常量是不
能修改的,那么如下代码是不允许的: char str[10]; str++; 但如下代码则合法的: char str[10]; char *pstr=str; pstr++;
数组或是在静态存储区被创建(全局数 组),或是在栈上被创建。数组名对应着,注 意不是指向,一块内存,其地址与容量在生命 期内保持不变(当然,使用了realloc()的不 算),只有数组的内容可以改变。 指针可以随时指向任意类型的内存块,它 的特征是“可变”,所以我们常用指针来操作动 态内存。指针远比数组灵活,当然也就更危险。

char
str[10]; char *pstr=str; cout<<sizeof(str); cout<<sizeof(pstr); 第一行输出结果是:10,第二行输出结果是: 4
数组名对应着(而不是指向)一块内存(数组
所占的内存区域)或者说是指代数组这种数据 结构,其地址与容量在生命期内保持不变,只 有数组的内容可以改变。指针对应着一个占据4 个字节(Win32)的内存区域,而指向这4个字 节所存储的地址所对应的内存单元,它可以指 向任意类型的内存块。因此,sizeof(str)值为数 组占据的内存空间大小即10个字节,而 sizeof(pstr)值为指针的值占据的内存空间大小 即4个字节。
相关文档
最新文档