C语言指针用法难点

合集下载

转载:C语言指针使用的注意事项

转载:C语言指针使用的注意事项

转载:C语⾔指针使⽤的注意事项相信⼤家对指针的⽤法已经很熟了,这⾥也不多说些定义性的东西了,只说⼀下指针使⽤中的注意事项吧。

⼀.在定义指针的时候注意连续声明多个指针时容易犯的错误,例如int * a,b;这种声明是声明了⼀个指向int类型变量的指针a和⼀个int型的变量b,这时候要清醒的记着,⽽不要混淆成是声明了两个int型指针。

⼆.要避免使⽤未初始化的指针。

很多运⾏时错误都是由未初始化的指针导致的,⽽且这种错误⼜不能被编译器检查所以很难被发现。

这时的解决办法就是尽量在使⽤指针的时候定义它,如果早定义的化⼀定要记得初始化,当然初始化时可以直接使⽤cstdlib中定义的NULL也可以直接赋值为0,这是很好的编程习惯。

三.指针赋值时⼀定要保证类型匹配,由于指针类型确定指针所指向对象的类型,因此初始化或赋值时必须保证类型匹配,这样才能在指针上执⾏相应的操作。

四.void * 类型的指针,其实这种形式只是记录了⼀个地址罢了,如上所说,由于不知道所指向的数据类型是什么所以不能进⾏相应的操作。

其实void * 指针仅仅⽀持⼏种有限的操作:1.与另外的指针进⾏⽐较,因为void *类型⾥⾯就是存的⼀个地址,所以这点很好理解;2.向函数传递void *指针或从函数返回void *指针,举个例⼦吧,我们平时常⽤的库函数qsort中的⽐较函数cmp(个⼈习惯于⽤这个名字)中传递的两个参数就是const void *类型的,⽤过的应该很熟了;3.给另⼀个void * 类型的指针赋值。

还是强调⼀下不能使⽤void * 指针操纵它所指向的对象。

五.不要将两个指针变量指向同⼀块动态内存。

这个容易引起很严重的问题。

如果将两个指针变量指向同⼀块动态内存,⽽其中⼀个⽣命期结束释放了该动态内存,这个时候就会出现问题,另⼀个指针所指向的地址虽然被释放了但该指针并不等于NULL,这就是所谓的悬垂指针错误,这种错误很难被察觉,⽽且⾮常严重,因为这时该指针的值是随机的,可能指向⼀个系统内存⽽导致程序崩溃。

C语言指针教学重点和难点问题浅析

C语言指针教学重点和难点问题浅析

C语言指针教学重点和难点问题浅析一、教学重点1. 指针的概念和基本语法指针是C语言中的一个重要概念,它是存储其他变量地址的变量。

在介绍指针的概念时,需要着重强调指针变量和指针地址的概念,并且让学生能够理解指针变量中存储的是其他变量的地址。

需要讲解指针变量的声明和基本语法,包括指针变量的定义、取地址运算符&和解引用运算符*的使用等。

2. 指针和数组的关系指针与数组是C语言中的两个重要概念,它们之间有着密切的关系。

在教学中需要说明指针和数组的关系,包括数组名即为数组首元素地址、指针与数组名的关系以及指针和数组的相互转换等。

这对于学生理解指针的概念和用法是非常重要的。

指针在C语言中与函数有着密切的联系,通过指针参数可以实现函数的参数传递和返回多个值等功能。

在教学中需要重点介绍指针作为函数参数的用法,包括指针作为参数的函数声明和调用、指针作为函数返回值的用法等。

4. 指针和动态内存分配动态内存分配是C语言中一个重要的概念,也是指针的一个重要应用。

在教学中需要说明动态内存分配的概念和使用方法,包括用malloc、calloc和realloc等函数动态分配内存,以及用free函数释放动态分配的内存。

需要强调动态内存分配的过程中需要注意内存泄漏和内存溢出等问题。

1. 指针的复杂性指针作为C语言中的一个重要概念,其本身的复杂性是教学的一个难点。

指针的概念抽象,对初学者来说不容易理解和掌握,尤其是对于没有编程经验的学生来说更是一项挑战。

在教学中需要采用生动形象的比喻和例子,让学生可以通过具体的例子理解指针的概念和用法。

指针的使用很容易导致内存管理方面的问题,比如内存泄漏、野指针等。

这些问题对于学生来说是一个较大的难点,在教学中需要重点讲解指针导致的内存管理问题,比如动态内存分配和释放等,以及如何避免和解决这些问题。

三、教学方法针对上述教学重点和难点,教师可以采用以下教学方法:1. 生动形象的比喻和例子在教学中可以采用生动形象的比喻和例子,让学生通过具体的例子理解抽象的概念,比如用指针来比喻门牌号、邮政编码等,让学生理解指针的概念和用法。

C语言指针要点总结

C语言指针要点总结

C语言指针要点总结C语言是一种面向过程的编程语言,而指针是C语言中的一个核心概念。

掌握指针的使用对于理解和运用C语言来说非常重要。

下面是C语言指针的一些要点总结:指针是一个变量,用于存储另一个变量的地址。

指针的声明使用*符号来标识,例如:int *ptr; 表示ptr是一个指向int类型的指针。

2.指针的初始化:指针在使用之前必须被初始化,可以通过直接赋值给指针变量、取地址符&,或者使用malloc函数(用于动态分配内存)来初始化指针。

3.指针的操作:3.1指针的解引用:解引用指针意味着访问指针指向的内存地址上的值。

可以使用*操作符来解引用指针,例如:*ptr 表示访问指针ptr指向的内存地址上的值。

3.2指针的递增和递减:指针可以通过递增和递减操作来指向相邻的内存地址。

递增操作使用++操作符,递减操作使用--操作符,例如:ptr++ 表示将指针ptr指向下一个内存地址。

4.指针的算术运算:指针支持算术运算,可以进行指针之间的加法、减法运算。

指针之间的加法运算会根据指针类型的大小来计算结果的地址。

5.数组和指针的关系:数组和指针在C语言中有着紧密的关系。

数组名本身就是一个指针,指向数组的第一个元素的地址。

可以使用指针来操作数组元素,例如:*(arr + i) 表示访问数组arr中的第i个元素。

6.指针作为函数参数:使用指针作为函数的参数,可以实现在函数中修改传入参数的值。

将参数声明为指针类型,可以直接修改参数所指向的内存地址上的值,而不仅仅是操作参数的副本。

7.动态内存分配:可以使用malloc函数来动态分配内存,返回一个指向所分配内存的指针。

动态内存分配可以在程序运行时根据需要进行内存分配和释放,这对于处理动态数据结构非常有用。

8.空指针和野指针:空指针表示指针不指向任何有效的内存地址,可以用NULL来表示。

野指针是指指针指向未初始化或已释放的内存地址,使用野指针是非常危险的,可能导致程序崩溃或非预期的行为。

c语言指针注意事项

c语言指针注意事项

1. 初始化防止出现未知内存操作危险
指针一定要初始化后进行解引用操作(*p),不然可能出现对未知内存块的操作。

原因是不初始化的指针一开始的指向是随机的。

2.指针在动态内存分配的应用
new分配内存,返回地址。

delete删除指针指向内存,但不会删除指针(变量)本身。

new和delete应成对使用,否则发生内存泄露。

内存泄露:指的是那些被分配的内存由于没有进行回收处理,无法再进行使用。

几点注意:
不用delete释放不是new分配的内存
不要使用delete释放同一内存两次
如果使用new []为数组分配内存,应使用delete [] 来释放
3.指针可以当数组使用
type* p = new type [num] p[0] = xxx p[1] = yyy
原因:C/C++对于数组的编译解释都是将数组名看做一个地址(首个元素的地址)。

区别在于,数组名是常量,但指针可以修改。

另外,对数组用sizeof可以得到数组长度,但是对指针用sizeof只能得到指针长度(地址长度)。

4.指针的算术
指针是地址,所以指针的加减实际上是地址的加减。

指针变量+1,增加的量是它指向类型的字节数。

5.指向结构体的指针怎么访问结构内的成员
箭头成员运算符或者(*p).xxx的形式。

记住核心:p是指向数据对象的地址,*p就是所指向的数据对象。

指针教学中的难点解析

指针教学中的难点解析
机 试 中 的 重 点 考 查 内容 。 过 我 们 的 教 学 实 践 和 对 等 级 考 试 通 的 总 结 , 生通 过 学 习 能够 较 好 掌 握 指 针 变 量 与 基 本 数 据 类 学
例 1有 如 下 说 明 语 句 ( 例 题 及 其 后 文 中 的程 序 均 在 本
T roC 2 1 统 下讨 论 ) u b . 系 0 : sai n 3 q { , , , , , , , , ,0 1 ,2 , j tt t [】 = 1 2 3 4 5 6 7 8 9 1 , 1 1 )i ; ci a [ , sai f a b牛 { _, ., . ,.} tt o t [ l 2 35 45; c l 5 5
下 面 , 们 应用 地址 级 别和地址 类型的概 念 , 结 合实 我 并
例 , 多 维 数 组 进 行 深 入 的讨 论 。 对
视 , 其 中指 针 是 C语 言 的精 华 部 分 和 难 点 部 分 , 学 好 c 而 是 语 言 的 关 键 ,也 是 学 生 期 末 考 试 和 计 算机 等 级 考 试 的 笔 试 、
为 n 为 叙 述 方便 , 将 之 记 为 s e f 识 符 ) n 由于 it , 则 i o( z 标 =。 n型
数 据 在 内存 中 占 2个 字 节 ( zoit 2, 以有 s ef)2 。 s e fn) )所 i ( = i o a 4 z (= b是 一 维 数 组 的 数 组 名 , “ 级 地 址 ”其 地 址 类 型 是 是 一 , l t ]。 f a4* 由于 f a 型 数 据 在 内存 中 占 4个 字节 ( zo(o t o[ l t o s ef a) i f - l
紧 密 关 联 , 指 针 教 学 中 的 难 点 。通 过 应 用 指 针 级 别 和 地 址 类 型 的 概 念 , 结 合 相 应 的 程 序 实 例 可 以 阐 明这 些 数 组 与 是 并

C语言指针教学重点和难点问题浅析

C语言指针教学重点和难点问题浅析

C语言指针教学重点和难点问题浅析一、教学重点1. 指针定义指针是一个变量,它存储的是一个地址,指向另一个变量的地址。

指针变量必须先定义,然后才能使用。

指针变量定义的语法为:类型 *指针变量名;其中,类型是指该指针变量所指向的变量的类型,指针变量名则是任意合法的变量名。

例如:int *p; 表示定义了一个指针变量p,它指向一个整型数。

2. 指针运算指针运算是指对指针变量进行的各种操作,例如,取地址运算(&)、解引用运算(*)、指针加法、指针减法等等。

其中,取地址运算就是获取一个变量的地址,解引用运算则是将指针变量所指向的地址中存储的值取出来。

3. 指针和数组在C语言中,数组和指针有着密切的联系和关系。

事实上,数组本身就是一个指针,它存储的是一段连续的内存空间的地址。

因此,可以通过指针来操作数组,例如,可以用指针变量遍历数组中的每一个元素。

4. 动态内存分配动态内存分配是指在程序运行期间,根据需要动态地申请或释放内存空间。

在C语言中,动态内存分配是通过使用malloc()、realloc()和free()等函数来实现的。

这些函数可以根据需要来申请所需大小的内存空间,并在使用完成后将其释放,以防止内存泄漏的问题。

二、难点问题1. 指针变量的应用和使用指针变量是一个比较抽象和难以理解的概念,对于初学者来说,往往需要花费较长的时间来理解和掌握。

同时,指针变量还涉及到指针的运算和指针和数组等内容,这就增加了学习的难度。

指针运算是指针操作中比较重要且常用的一类操作,例如指针加、减、取地址运算等等。

但是,指针运算也存在一些需要注意的问题,例如指针越界访问、类型转换等问题,在使用指针运算时需要特别小心。

综上所述,C语言中的指针是一项比较重要、也比较复杂的内容,掌握和理解指针的使用和原理是掌握C语言的关键所在。

因此,在教学中,应该注重指针的基本概念和原理的讲解,同时也要注意指针运算和动态内存分配等难点内容的教学。

C语言第7章_指针

C语言第7章_指针

退出
指针运算
算术运算 int *p, a[10]; p = a; p++; /*p的值增加多少?*/ 的值增加多少? 的值增加多少 指针的加减运算是以其指向的 指针的加减运算是以其指向的 类型的字节长度为单位的 类型的字节长度为单位的
6000 6001 6002 6003 6004 6005 6006
swap函数的几种错误形式(3/3) 函数的几种错误形式 3/3)
指针p没有确切地址 指针 没有确切地址 void Swap(int *p1, int *p2) { int *p; /*指针 未初始化*/ /*指针p未初始化*/ 指针p未初始化 *p = *p1; *p1 = *p2; *p2 = *p; }
退出
寻址方式
如何读写内存中的数据? 如何读写内存中的数据? 两种寻址方式 直接(寻址)访问 直接(寻址)
通过变量地址直接存取变量内容
0 ┇ 3 6 9 ┇ 3010 2000 变量 i_pointer 变量 i 变量 j 变量 k 内存用户数据区
通过变量的地址访问变量所在的 2000 存储单元
2002 2004
退出
指针运算
赋值运算 指针在使用前一定要赋值 为指针变量赋的值必须是一个地址 main() { int *p; scanf("%d",p); … }
错! 但TC下不报错 下不报错 VC下报错 下报错
main() { int a,*p=&a; scanf("%d",p); … }
退出
指针与函数
指针既然是数据类型,自然可以做函数参数和返回值 指针既然是数据类型, 的类型 指针做函数参数的经典例子: 指针做函数参数的经典例子:

C语言中指针应用的常见问题

C语言中指针应用的常见问题
2使 用 指 针 法 访 问数 组 元 素 时 。 注 意 “ 标 是 否越 界 ” . 要 下 的 问题 。 + 表示 a 4 面 的一 个 整 型 单 元 。 样 会 破 坏有 用 的 p5 +下 这 数 据 , 生 不 应 有 的后 果 , 重 地 造 成 死 机 ,编 译 系统 并 不 指 产 严 c 出 “ 标 越 界 ” 样 的错 误 下 这 3使 用 指 向 数 组 元 素 的 指 针 变 量 时 . 注 意 指 针 变量 的 . 应 当前值 。如 p a 0(= ; 5i+ saf“ ”p + 。若 缺 少 “= : ;ri0i . )cn( %d ,+ ) f < + p a” 一 语 句 , p ; 这 则 的值 是一 个 不 确 定 的值 , 的指 向不 确 定 。 它 有 可 能将 输 入 的5 个数 据输 入 到 难 以 预 料 的存 储 单 元 中 去 , 能 可 造 成 “ 难 性 ” 后 果 灾 的 4 两个 指 针 相 加 产 生错 误 。两个 指 针 是 不 能 相 加 的 如 果 . 你 的C 序试 图将 两 个 指 针 相 加 , 程 序 就 会 发 出警 告 。 当你 程 译 试 图将 一 个 指 针 和 另 外 两 个 指 针 的 差 值 相 加 的 时 候 ,你 很 可 能 会 误 将 其 中的 两 个 指 针 相 加 。例 如 。 你很 可 能会 使 用语 句 : ppp 一 l = + 2 p 。这 个 语 句 是 不 正 确 的 , 为 它 和语 句 p ( lp ) 因 = p+2一 p完 全 相 同 , 确 语 句 应 该 是 := + p 一 1 。 l 正 p p (2 p ) 四 、 针变 量 用 于 函数 时 应 注 意 的 问题 指 函数 的 返 回 值 不 仅 可 以 是 一 般 的 数 据 类 型 .还 可 以 为 指 针 类 型 , 种 带 回的 类 型 为指 针 的 函数 称 为 指 针 函数 。对 于 这 函数 带 回的 指针 , 个 指 针 所 指 示 的存 储 单 元 必 须 是 存 在 的 , 这 不 可 以 不存 在 。例 如 : it n ma (n ,n x it it x Y)

c语言指针函数的用法

c语言指针函数的用法

c语言指针函数的用法一、引言在C语言中,指针函数是一种特殊类型的函数,它接受一个指针作为参数,或者返回一个指针作为结果。

通过使用指针函数,我们可以更灵活地操作内存,实现对数据类型的深入理解和掌握。

本篇文章将详细介绍指针函数的定义、调用以及注意事项。

二、指针函数的定义1. 定义形式:类型 * 函数名(参数列表) { 函数体 }2. 说明:类型是指针所指向的数据类型;* 表示这是一个指针函数,即该函数接收一个指针作为参数或者返回一个指针;函数名是自定义的名称,需要符合C语言命名规范;参数列表表示函数的输入参数,可以有多个;函数体包含了函数的功能实现。

三、指针函数的调用1. 形式:指针变量 = 函数名(参数列表);2. 说明:首先需要声明一个合适的指针变量,然后将该变量传递给指针函数,函数执行完毕后,指针变量的值会发生改变。

【示例代码】假设有一个整数数组arr[],我们要找到其中最大的元素并返回其索引。

可以定义一个指向函数的指针变量fp,并将它传递给一个指针函数max_index来找到最大元素的索引。

代码如下:int *fp;int max_index(int *arr, int n) {int *max = arr; // 假设第一个元素是最大值for (int i = 1; i < n; i++) {if (*(arr + i) > *max) { // 比较当前元素与最大值的大小max = arr + i; // 更新最大值}}return max; // 返回最大值的地址}fp = max_index; // 将max_index函数的地址赋值给fpprintf("最大元素的索引为:%d\n", fp); // 调用fp即可输出最大元素的索引四、注意事项1. 指针函数不能没有返回值,否则会编译错误。

如果需要返回一个指针,则需要确保返回值指向的空间足够大。

2. 传递给指针函数的参数必须是合适的指针类型,否则会编译错误。

C语言指针用法难点(详解)

C语言指针用法难点(详解)

C语言指针用法难点指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。

让我们分别说明。

先声明几个指针放着做例子:例一:(1)int*ptr;(2)char*ptr;(3)int**ptr;(4)int(*ptr)[3];(5)int*(*ptr)[4];如果看不懂后几个例子的话,请参阅我前段时间贴出的文章<<如何理解c和c ++的复杂类型声明>>。

指针的类型从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。

这是指针本身所具有的类型。

让我们看看例一中各个指针的类型:(1)int*ptr;//指针的类型是int*(2)char*ptr;//指针的类型是char*(3)int**ptr;//指针的类型是int**(4)int(*ptr)[3];//指针的类型是int(*)[3](5)int*(*ptr)[4];//指针的类型是int*(*)[4]怎么样?找出指针的类型的方法是不是很简单?指针所指向的类型当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。

从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。

例如:(1)int*ptr;//指针所指向的类型是int(2)char*ptr;//指针所指向的的类型是char(3)int**ptr;//指针所指向的的类型是int*(4)int(*ptr)[3];//指针所指向的的类型是int()[3](5)int*(*ptr)[4];//指针所指向的的类型是int*()[4]在指针的算术运算中,指针所指向的类型有很大的作用。

指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。

c语言指针的用法

c语言指针的用法

c语言指针的用法c语言是一种高级编程语言,它可以直接操作内存中的数据。

指针是c语言中一种特殊的变量,它可以存储另一个变量的地址,也就是内存中的位置。

通过指针,我们可以间接地访问或修改内存中的数据,从而实现更高效和灵活的编程。

本文将介绍c语言指针的基本概念、定义和初始化、运算和应用,以及一些常见的错误和注意事项。

希望本文能够帮助你掌握c语言指针的用法,提高你的编程水平。

指针的基本概念指针是一种数据类型,它可以存储一个地址值,也就是内存中某个位置的编号。

每个变量在内存中都有一个唯一的地址,我们可以用指针来记录这个地址,然后通过这个地址来访问或修改变量的值。

例如,假设有一个整型变量a,它的值为10,它在内存中的地址为1000(为了简化,我们假设地址是十进制数)。

我们可以定义一个指向整型的指针p,并把a的地址赋给p,如下所示:int a =10; // 定义一个整型变量a,赋值为10int*p; // 定义一个指向整型的指针pp =&a; // 把a的地址赋给p这里,&a表示取a的地址,也就是1000。

p = &a表示把1000赋给p,也就是让p指向a。

从图中可以看出,p和a是两个不同的变量,它们占用不同的内存空间。

p存储了a的地址,也就是1000。

我们可以通过p 来间接地访问或修改a的值。

指针的定义和初始化指针是一种数据类型,它需要在使用前进行定义和初始化。

定义指针时,需要指定它所指向的变量的类型。

初始化指针时,需要给它赋一个有效的地址值。

定义指针的一般格式为:type *pointer_name;其中,type表示指针所指向的变量的类型,如int、char、float等;pointer_name表示指针的名称,如p、q、ptr等;*表示这是一个指针类型。

例如:int*p; // 定义一个指向整型的指针pchar*q; // 定义一个指向字符型的指针qfloat*ptr; // 定义一个指向浮点型的指针ptr注意,在定义多个指针时,每个指针前都要加*号,不能省略。

C语言指针教学难点解析

C语言指针教学难点解析

职 业教 育 ・
青年 时 代
Y O U T H T I M E S
2 0 1 5 年 第 2 l 期
c 语 言指 针教学难 点解析
曹 挚
江苏 徐州 2 2 1 0 0 4 徐州幼儿师 范高等专科学校 摘
要 :指针 是c 语 言的核 心和灵魂 ,也是c 语 言最难 掌握 的部分。本文深入 分析 了指针 的概念和指针 变量 的用法 ,针

两个数 据的指针 ,然后将它们 的值传递 给同样是指针变量 的 形参 ,才能实现主函数中两个数字的交换 。 四 、指 针与 数组 指 针与 数 组有 着 十 分 紧 密 的联 系 。首 先 ,一 维数 组 名其 实就 是一个 指针 常量 ,存放 的是数组第 一个 元素 的地 址 ,指 向数 组 中的第一个元 素 。设 数组名 为a r r a y ,则 第一 个元 素为a r r a y [ O ] 。可 以理解 为 :a r r a y 一 &a r r a y 【 O 】 ,注意 , 这 里不可 以对数组 名a r r a y 进行 赋值 ,如下面 的语句 是错误


元 的编号 , 类 似于宾馆 的房间号。顾名思义 , 指针指向了一个 特定的内存单 元,通过指针能够找到以指针为地址的变量 中的 内容。c 语言中取地址符是&,如定义一个整型变量i n t i ,& 蹴 是i 的地址 ,&i 可以理解为一个指针常量 。从数 的范围上说 , 指针是从零开始的一个非负整数 。C 语 言程序通过指针能够直 接访问地址 ,能够方便地处理字符 串。同时 ,学好指针对理解 今后面 向对象语言中的引用有着很好的作用。 二 、指 针变量 从 上面指 针 的定义 可以知道 ,一个 变量 的地址 就是该 变量 的指针 ,如果有一个 变量专 门用来存放另一个变 量的地 址, 则称为 “ 指针变量 ”。指针变量就是存放 内存单元编号 的变量 ,或者说指针变量就是存放地址 的变量 。要注 意指针 和指针变量是两个不 同的概念 。指针是一个具体 的数值 ,可 以理解 为一个常量 ,而指针变量归根结底是一个变量 ,用来 存放地址 的 ,可 以被赋值 。根据指针变量所指 向的变量类 型 不 同,指针变量也分 为指 向整 型的指针变量 、指 向浮点 型的 指针变量 以及指 向字符型的指针 变量 。如定义指针变量 i m p ,则p 是一个变 量的名字 ,p 存放 的是整型变量 的地址 。这 里还可 以定 义一 个整型i ,并 将3 赋 给i ,语句如下 :i n t i =3 ; 将整型变量i 的地址 赋给指针变量P ,即p =& i 。这样 ,p 保存 了i 的地址 ,因此P 指 向i 。这里P 不是i ,i 也不是P ,更准确地 说 :修 改P 的值 不影响i 的值 ,修 改i 的值 也不会影 响p 的值 。 p 表示得是 以P 的 内容为地址的变量 。这里 的含义有两种 , 种是定义 了一个名字 " q p 的变量 ,i n t + 表示P 只能存 放i n t 类 型变量 的地址 。第二种是表示指针运算符 ,放在 已经定义好 的指针变量 的前面 。这里 和&两 个符号 互为逆运算 。指 针 变量还可 以进行运算 。指针变量之 间不 能相加 ,不能相乘 ,

C语言难点及分析

C语言难点及分析

C语言难点及分析C语言是一种贴近硬件的高级编程语言,常用于嵌入式系统、操作系统和底层开发等领域。

虽然C语言相对于其他编程语言来说比较简单,但仍有一些难点需要注意和分析。

一、指针的理解和使用指针是C语言中的一个重要概念,也是相对较难的部分之一、学习指针的难点主要在于其抽象和概念的理解,以及指针的使用方式。

指针可以理解为内存地址,它指向存储单元的位置。

通过指针可以直接操作内存中的数据,使得程序更加高效灵活。

但是,指针的错误使用可能导致程序崩溃或产生未知的结果,因此需要特别小心。

指针的难点主要表现在以下几个方面:1.指针和变量的关系理解:指针和变量之间是一种间接关系,指针是存储变量地址的变量。

2.指针的声明和初始化:指针变量的声明和初始化需要注意语法和语义的细节,如指针的类型和指针所指向的数据类型。

3.指针的运算和使用:指针可以进行递增和递减运算,也可以用于数组、函数和结构体等复杂数据结构的操作。

二、内存管理C语言中,需要手动进行内存的申请和释放,这是相对于高级语言的一种特殊机制。

内存的申请和释放需要遵循一定的规则,否则可能会引发内存泄漏或者野指针的问题。

内存管理的难点主要表现在以下几个方面:1. 动态内存分配:动态内存分配是指在程序运行过程中根据需要申请和释放内存。

C语言中提供了动态内存分配的函数,如malloc、calloc和realloc等,但需要特别注意内存的申请大小和合理的内存释放。

2.内存泄漏和野指针:内存泄漏是指程序申请到内存后,没有进行正确释放导致内存一直占用。

而野指针是指指向无效内存地址的指针,可能会引发程序崩溃或产生未知的错误结果。

三、字符串的处理C语言中,字符串是以字符数组的形式来表示的。

字符串的处理涉及到字符的操作、字符串的拼接和比较、字符串的查找和替换等功能,对于初学者来说可能比较困难。

字符串处理的难点主要表现在以下几个方面:1.字符串数组和字符数组的区别:字符串必须以'\0'结尾,表示字符串的结束符,而字符数组可以不需要。

c语言指针赋值和memcpy赋值的注意事项

c语言指针赋值和memcpy赋值的注意事项

c语言指针赋值和memcpy赋值的注意事项在C语言中,指针和内存拷贝(memcpy)是非常重要的概念,但它们的使用也带来了许多需要注意的地方。

以下是关于指针赋值和memcpy赋值的一些注意事项:1.指针赋值:o确保指针在使用之前已经被正确初始化。

未初始化的指针可能导致未定义的行为。

o避免悬挂指针(dangling pointer)。

当指针指向一个已被释放的内存块时,再次使用该指针是危险的。

o避免野指针(wild pointer)。

这是指向未分配内存的指针。

o当指向的内存被释放后,确保将指针设置为NULL,以防止野指针的产生。

o使用指针进行内存操作时,应确保有足够的权限和空间。

2.memcpy赋值:o memcpy用于拷贝内存块,但它不会检查目标内存区域是否足够大。

因此,使用memcpy时必须确保目标内存足够大以容纳源数据。

否则,可能会导致缓冲区溢出,这是一个严重的安全问题。

o当使用memcpy拷贝结构体或类时,需要注意结构的对齐和填充。

不同平台和编译器可能对结构体的对齐有不同的要求,这可能导致拷贝后的结构体与原始结构体在字节级别上有所不同。

o memcpy不会处理重叠的内存区域。

如果需要拷贝重叠的内存区域,应使用memmove。

o memcpy不会检查源和目标内存区域是否重叠。

如果需要检查重叠,可以使用_memmove_s(在某些平台和编译器上可用)。

为了安全和有效地使用指针和内存拷贝,建议遵循以下最佳实践:•初始化所有指针变量。

•在使用指针之前,检查它们是否为NULL。

•使用智能指针(如std::unique_ptr和std::shared_ptr)来管理动态分配的内存,以减少内存泄漏和野指针的风险。

•使用strncpy或strncat等函数代替strcpy和strcat,以防止缓冲区溢出。

•使用sizeof操作符来检查目标内存区域是否足够大。

•在使用memcpy时,确保目标内存区域足够大,并考虑结构体的对齐和填充问题。

c语言的知识点,难点

c语言的知识点,难点

c语言的知识点,难点C语言知识点和难点C语言作为一门经典的编程语言,有着广泛的应用领域和深厚的底蕴。

在学习和使用C语言的过程中,我们常常会遇到一些知识点和难点,下面就来介绍一些常见的问题和解决方法。

一、指针指针是C语言的一个重要概念,也是初学者常常会遇到的难点之一。

指针可以说是C语言的核心,它的灵活运用可以提高程序的效率和灵活性。

但是指针也容易引发一些问题,如空指针、野指针等。

为了避免这些问题的发生,我们需要养成良好的指针使用习惯,如在使用指针之前进行判空操作、指针赋值后及时释放等。

二、内存管理C语言中没有自动垃圾回收机制,我们需要手动管理内存的分配和释放。

这就需要我们对内存的分配和释放函数有一定的了解,如malloc、free等。

同时,在使用动态内存分配时,还需要注意内存泄漏和内存溢出的问题,避免程序运行过程中出现不可预料的错误。

三、数组和字符串数组和字符串是C语言中常用的数据结构,但也是初学者容易出错的地方。

在使用数组和字符串时,需要注意数组越界、字符串结束符以及字符串长度等问题。

尤其是在进行字符串处理时,要避免缓冲区溢出和字符串拼接的问题,以免造成安全漏洞。

四、文件操作C语言提供了丰富的文件操作函数,如打开文件、读写文件、关闭文件等。

在进行文件操作时,需要注意文件打开失败、文件读写错误和文件关闭等问题。

同时,在读写文件时,还需要注意文件指针的位置以及文件操作模式等,以免造成数据丢失或错误。

五、逻辑控制和循环逻辑控制和循环是C语言程序的基础,也是初学者需要掌握的重点。

在使用逻辑控制和循环语句时,需要注意条件判断的准确性和循环变量的更新等问题。

同时,在编写循环时,还需要注意循环的退出条件和循环体的执行顺序,以免出现死循环或逻辑错误。

六、函数和模块化函数和模块化是C语言的重要特性,也是编写高质量程序的关键。

在编写函数时,需要注意函数的命名规范、参数的传递和返回值的处理等问题。

同时,要养成良好的模块化编程习惯,将程序划分为多个函数,提高代码的可读性和可维护性。

C语言指针知识点总结

C语言指针知识点总结

C语⾔指针知识点总结1.指针的使⽤和本质分析(1)初学指针使⽤注意事项1)指针⼀定要初始化,否则容易产⽣野指针(后⾯会详细说明);2)指针只保存同类型变量的地址,不同类型指针也不要相互赋值;3)只有当两个指针指向同⼀个数组中的元素时,才能进⾏指针间的运算和⽐较操作;4)指针只能进⾏减法运算,结果为同⼀个数组中所指元素的下表差值。

(2)指针的本质分析①指针是变量,指针*的意义:1)在声明时,*号表⽰所声明的变量为指针。

例如:int n = 1; int* p = &n;这⾥,变量p保存着n的地址,即p<—>&n,*p<—>n2)在使⽤时,*号表⽰取指针所指向变量的地址值。

例如:int m = *p;②如果⼀个函数需要改变实参的值,则需要使⽤指针作为函数参数(传址调⽤),如果函数的参数数据类型很复杂,可使⽤指针代替。

最常见的就是交换变量函数void swap(int* a, int* b)③指针运算符*和操作运算符的优先级相同例如:int m = *p++;等价于:int m= *p; p++;2.指针和数组(1)指针、数组、数组名如果存在⼀个数组 int m[3] = {1,2,3};定义指针变量p,int *p = m(这⾥m的类型为int*,&a[0]==>int*)这⾥,其中,&m为数组的地址,m为数组0元素的地址,两者相等,但意义不同,例如:m+1 = (unsigned int)m + sizeof(*m)&m+1= (unsigned int)(&m) + sizeof(*&m)= (unsigned int)(&m) + sizeof(m)m+1表⽰数组的第1号元素,&m+1指向数组a的下⼀个地址,即数组元素“3”之后的地址。

等价操作:m[i]←→*(m+i)←→*(i+m)←→i[m]←→*(p+i)←→p[i]实例测试如下:1 #include<stdio.h>23int main()4 {5int m[3] = { 1,2,3 };6int *p = m;78 printf(" &m = %p\n", &m);9 printf(" m = %p\n", m);10 printf("\n");1112 printf(" m+1 = %p\n", m + 1);13 printf(" &m[2] = %p\n", &m[2]);14 printf(" &m+1 = %p\n", &m + 1);15 printf("\n");1617 printf(" m[1] = %d\n", m[1]);18 printf(" *(m+1) = %d\n", *(m + 1));19 printf(" *(1+m) = %d\n", *(1 + m));20 printf(" 1[m] = %d\n", 1[m]);21 printf(" *(p+1) = %d\n", *(p + 1));22 printf(" p[1] = %d\n", p[1]);2324return0;25 }输出结果为:(2)数组名注意事项1)数组名跟数组长度⽆关;2)数组名可以看作⼀个常量指针;所以表达式中数组名只能作为右值使⽤;3)在以下情况数组名不能看作常量指针:- 数组名作为sizeof操作符的参数- 数组名作为&运算符的参数(3)指针和⼆维数组⼀维数组的指针类型是 Type*,⼆维数组的类型的指针类型是Type*[n](4)数组指针和指针数组①数组指针1)数组指针是⼀个指针,⽤于指向⼀个对应类型的数组;2)数组指针的定义⽅式如下所⽰:int (*p)[3] = &m;②指针数组1)指针数组是⼀个数组,该数组⾥每⼀个元素为⼀个指针;2)指针数组的定义⽅式如下所⽰:int* p[5];3.指针和函数(1)函数指针函数的本质是⼀段内存中的代码,函数的类型有返回类型和参数列表,函数名就是函数代码的起始地址(函数⼊⼝地址),通过函数名调⽤函数,本质为指定具体地址的跳转执⾏,因此,可定义指针,保存函数⼊⼝地址,如下所⽰:int funcname(int a, int b);int(*p)(int a, int b) = funcname;上式中,函数指针p只能指向类型为int(int,int)的函数(2)函数指针参数对于函数int funcname(int a, int b);普通函数调⽤ int funcname(int, int),只能调⽤函数int func(int, int)函数指针调⽤ intname(*func)(int,int),可以调⽤任意int(int,int)类型的函数,从⽽利⽤相同代码实现不同功能,实例测试如下,假设有两个相同类型的函数func1和func2:1int func1(int a, int b, int c)2 {3return a + b + c;4 }56int func2(int a, int b, int c)7 {8return a - b - c;9 }普通函数调⽤和函数指针调⽤⽅式及结果如下所⽰1 printf("普通函数调⽤\n");2 printf("func1 = %d\n", func1(100, 10, 1));3 printf("func2 = %d\n", func2(100, 10, 1));4 printf("\n");56 printf("函数指针调⽤\n");7int(*p)(int, int, int) = NULL;8 p = func1;9 printf("p = %d\n", p(100, 10, 1));10 p = func2;11 printf("p = %d\n", p(100, 10, 1));12 printf("\n");需要注意的是,数组作为函数参数的时候,会变为函数指针参数,即:int funcname( int m[] )<——>int funcname ( int* m );调⽤函数时,传递的是数组名,即funcname(m);(3)回调函数利⽤函数指针,可以实现⼀种特殊的调⽤机制——回调函数。

c语言关于指针用的时候的问题

c语言关于指针用的时候的问题

指针是C语言中的一种特殊类型,它存储了一个数据对象的内存地址。

使用指针可以方便地访问和修改内存中的数据对象,使程序可以更加灵活和高效地操作数据。

以下是几个常见的指针使用问题及其解决方法:
1. 悬空指针:当指针指向的内存被释放或者指针没有被初始化时,指针就会失效,我们称这样的指针为"悬空指针"。

对悬空指针进行操作可能会导致程序崩溃或者出现不可预期的错误。

避免产生悬空指针的常见方法是在使用指针之前先将其初始化,并且在释放内存后将指针设置为NULL。

2. 内存泄漏:使用指针操作内存时,容易出现无法使用delete 或free 释放已经分配出去的内存的情况,从而导致内存泄漏。

内存泄漏会导致程序运行速度变慢、内存空间不足等问题,甚至会导致程序崩溃。

避免内存泄漏的方法是在使用malloc 或new 进行内存分配后,使用对应的free 或delete 释放内存。

3. 指针越界:指针越界是指指针所指向的内存范围已经超出了其所在变量的内存范围。

这种行为会引发各种问题,包括异常、崩溃和难以追踪的bug。

为了避免指针越界问题,应该始终注意尽可能精确地掌握指针的位置,并在使用指针的过程中特别留意边界情况。

总之,指针是一种非常重要且又危险的机制,要善用指针,必须对其特性和操作细节有一定的了解。

在使用指针的过程中,应该时刻注意指针的状态和指向内存的范围,这样才能更好地保证程序的正确性和可靠性。

指针易错知识点总结

指针易错知识点总结

指针易错知识点总结一、悬空指针悬空指针是指一个指针指向了已经被释放的内存地址,或者指向了未初始化的内存地址。

悬空指针的存在会导致程序运行时错误。

为了避免悬空指针的产生,我们需要严格控制指针的生命周期,确保指针只在有效的内存地址上操作。

二、野指针野指针是指一个指针指向了一个无效的内存地址,这个内存地址可能是未分配的内存,也可能是已经释放的内存。

野指针的存在同样会导致程序运行时错误。

为了避免野指针的产生,我们可以在指针被释放后,立刻将指针置为NULL,这样就可以避免野指针的操作。

三、指针的运算在C语言中,指针可以进行加法运算和减法运算。

加法运算可用于指针的偏移,而减法运算可用于计算两个指针之间的距离。

但是,在进行指针运算时,要确保运算结果不会超出有效的内存范围,否则会导致指针越界的错误。

另外,指针运算还需要考虑指针的类型,因为不同类型的指针在进行运算时,会有不同的规则。

四、指针和数组在C语言中,指针和数组之间存在着密切的关系。

数组名本身就是一个指针常量,它存储了数组第一个元素的内存地址。

因此,我们可以通过数组名和指针来对数组进行访问。

但是,要注意数组的越界访问,因为数组的越界访问同样会导致内存访问错误。

五、指针和函数指针和函数之间也有着紧密的联系。

我们可以通过指针将函数的地址传递给其他函数,从而实现函数的回调操作。

但是,在使用指针传参时,要确保传参正确,避免指针传递的错误。

六、指针和结构体指针和结构体的关系也非常密切。

我们可以通过指针来操作结构体的成员,或者通过指针来动态创建结构体。

但是,在使用指针操作结构体时,也需要确保指针的合法性,避免指针操作的错误。

七、指针和内存分配在C语言中,我们可以通过malloc和free函数来进行动态内存分配和释放。

当使用malloc函数分配内存时,要确保分配的内存是充足的,并且在使用完后及时释放,避免内存泄露和野指针的产生。

总之,指针在C语言中是非常重要的数据类型,但是也是易错的。

C语言指针教学重点和难点问题浅析

C语言指针教学重点和难点问题浅析

C语言指针教学重点和难点问题浅析
C语言的指针是一项非常重要且常用的特性,理解和使用指针是学好C语言的关键之一。

本文将从教学重点和难点问题两个方面对C语言指针进行浅析。

教学重点:
1. 指针的概念和基本使用:指针是C语言中的一种数据类型,用于存储变量的内存地址。

指针变量的声明和初始化,以及通过指针访问变量的值是学习的重点之一。

2. 指针和数组:C语言中的数组本质上也是指针,学习如何使用指针来访问和操作数组元素是十分重要的。

理解数组名即代表数组首元素地址的特性对于理解指针和数组之间的关系也非常重要。

3. 指针和函数:C语言中的指针和函数有着密切的关系。

学习如何使用指针作为函数参数,实现函数间的数据传递和修改是C语言中的重点难点之一。

尤其是指针与指针的传递,需要深入理解指针的本质以及指针在函数传递中的特性。

4. 动态内存分配:学习如何使用指针进行动态内存分配是C语言中的重点之一。

通过学习malloc和free函数的使用,可以实现灵活的内存分配和释放,避免程序的内存泄漏和崩溃问题。

学习C语言指针需要理解指针的概念和基本使用、指针和数组的关系、指针和函数的传递以及动态内存分配等重点内容,并且需要克服指针和地址的混淆、指针和数组的关系理解困惑、指针和函数传递的困难以及内存泄漏和崩溃问题等难点问题。

通过深入理解和实践,才能熟练掌握C语言中的指针特性。

C语言指针教学难点透析

C语言指针教学难点透析

155计算机教育Computer Education第 1 期2017 年 1 月 10 日中图分类号:G642C 语言指针教学难点透析张忆文(华侨大学 计算机科学与技术学院,福建 厦门 361021)摘 要:指针既是C 语言的重点,又是教学难点。

文章从指针的基本概念入手,由浅入深地讨论指针教学的重点与难点,重点介绍指向数组元素的指针、指向数组的指针、指针数组、指针函数以及函数指针变量等容易混淆的概念,通过应用实例揭示它们之间的区别,进而阐释指针的实质。

关键词:C 语言;指针;函数;数组基金项目:华侨大学引进人才科研启动基金项目(2016BS104)。

作者简介:张忆文,男,讲师,研究方向为绿色计算、实时调度,zyw@。

文章编号:1672-5913(2017)01-0155-040 引 言C 语言程序设计在计算机程序设计语言中占有重要的一席之地,它以语法简洁紧凑、程序精炼、运算符和数据结构丰富、编程灵活、可移植性好而著称[1]。

然而由于教科书内容僵化、过于抽象,且授课的对象往往是大学低年级学生,造成某些知识点难以理解,甚至理解错误。

其中,C 语言指针教学就是公认的教学难点[2],因为指针是C 语言的一大特色,用途极其广泛,所以,如何让学生透彻地理解指针,避免在使用过程中不犯错误或者少犯错误,是C 语言教学中的一个重要问题。

1 指针的基本概念1.1 指针变量的定义所谓指针是指变量在内存中的地址,是一个常量,其实质是对地址的操作实现对数据的操作。

“&”和“*”是指针的两个最基本的运算符。

“&”是取地址运算符,也就是将变量在内存的地址取出来,其结合性为自右向左。

“*”是取内容运算符,也就是将指针变量所指向变量的值取出,其结合性为自左向右。

用来存放指针(地址)的变量成为指针变量。

其定义如下:类型标识符 *指针变量名表;例如:void main( ){(1) int i=20; (2) int *p;(3) p=&i;(4) printf(“i address is %x p address is %x *p=%d ”,&i ,&p ,*p);}语句(2)定义了指针变量p ,语句(3)对指针变量p 进行初始化,使它指向普通变量i 。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C语言指针用法难点指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。

让我们分别说明。

先声明几个指针放着做例子:例一:(1)int*ptr;(2)char*ptr;(3)int**ptr;(4)int(*ptr)[3];(5)int*(*ptr)[4];如果看不懂后几个例子的话,请参阅我前段时间贴出的文章<<如何理解c和c ++的复杂类型声明>>。

指针的类型从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。

这是指针本身所具有的类型。

让我们看看例一中各个指针的类型:(1)int*ptr;//指针的类型是int*(2)char*ptr;//指针的类型是char*(3)int**ptr;//指针的类型是int**(4)int(*ptr)[3];//指针的类型是int(*)[3](5)int*(*ptr)[4];//指针的类型是int*(*)[4]怎么样?找出指针的类型的方法是不是很简单?指针所指向的类型当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。

从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。

例如:(1)int*ptr;//指针所指向的类型是int(2)char*ptr;//指针所指向的的类型是char(3)int**ptr;//指针所指向的的类型是int*(4)int(*ptr)[3];//指针所指向的的类型是int()[3](5)int*(*ptr)[4];//指针所指向的的类型是int*()[4]在指针的算术运算中,指针所指向的类型有很大的作用。

指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。

当你对C越来越熟悉时,你会发现,把与指针搅和在一起的"类型"这个概念分成"指针的类型"和"指针所指向的类型"两个概念,是精通指针的关键点之一。

我看了不少书,发现有些写得差的书中,就把指针的这两个概念搅在一起了,所以看起书来前后矛盾,越看越糊涂。

指针的值,或者叫指针所指向的内存区或地址指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。

在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。

指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为si zeof(指针所指向的类型)的一片内存区。

以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。

指针所指向的内存区和指针所指向的类型是两个完全不同的概念。

在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。

以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里?指针本身所占据的内存区指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。

在32位平台里,指针本身占据了4个字节的长度。

指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。

指针的算术运算指针可以加上或减去一个整数。

指针的这种运算的意义和通常的数值的加减运算的意义是不一样的。

例如:例二:1、chara[20];2、int*ptr=a;......3、ptr++;在上例中,指针ptr的类型是int*,它指向的类型是int,它被初始化为指向整形变量a。

接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针ptr的值加上了sizeof(int),在32位程序中,是被加上了4。

由于地址是用字节做单位的,故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节。

由于char类型的长度是一个字节,所以,原来ptr是指向数组a的第0号单元开始的四个字节,此时指向了数组a中从第4号单元开始的四个字节。

我们可以用一个指针和一个循环来遍历一个数组,看例子:例三:intarray[20];int*ptr=array;...//此处略去为整型数组赋值的代码。

...for(i=0;i<20;i++){(*ptr)++;ptr++;}这个例子将整型数组中各个单元的值加1。

由于每次循环都将指针ptr加1,所以每次循环都能访问数组的下一个单元。

再看例子:例四:1、chara[20];2、int*ptr=a;......3、ptr+=5;在这个例子中,ptr被加上了5,编译器是这样处理的:将指针ptr的值加上5乘sizeof(int),在32位程序中就是加上了5乘4=20。

由于地址的单位是字节,故现在的ptr所指向的地址比起加5后的ptr所指向的地址来说,向高地址方向移动了20个字节。

在这个例子中,没加5前的ptr指向数组a的第0号单元开始的四个字节,加5后,ptr已经指向了数组a的合法范围之外了。

虽然这种情况在应用上会出问题,但在语法上却是可以的。

这也体现出了指针的灵活性。

如果上例中,ptr是被减去5,那么处理过程大同小异,只不过ptr的值是被减去5乘sizeof(int),新的ptr指向的地址将比原来的ptr所指向的地址向低地址方向移动了20个字节。

总结一下,一个指针ptrold加上一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。

ptrnew的值将比ptrold的值增加了n乘sizeof(ptrold所指向的类型)个字节。

就是说,ptrnew所指向的内存区将比ptrold所指向的内存区向高地址方向移动了n乘sizeof(ptrold所指向的类型)个字节。

一个指针ptrold减去一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。

ptrnew的值将比ptrold的值减少了n乘sizeof(ptrold所指向的类型)个字节,就是说,ptrnew所指向的内存区将比ptrold所指向的内存区向低地址方向移动了n 乘sizeof(ptrold所指向的类型)个字节。

运算符&和*这里&是取地址运算符,*是...书上叫做"间接运算符"。

&a的运算结果是一个指针,指针的类型是a的类型加个*,指针所指向的类型是a的类型,指针所指向的地址嘛,那就是a的地址。

*p的运算结果就五花八门了。

总之*p的结果是p所指向的东西,这个东西有这些特点:它的类型是p指向的类型,它所占用的地址是p所指向的地址。

例五:inta=12;intb;int*p;int**ptr;p=&a;//&a的结果是一个指针,类型是int*,指向的类型是int,指向的地址是a的地址。

*p=24;//*p的结果,在这里它的类型是int,它所占用的地址是p所指向的地址,显然,*p就是变量a。

ptr=&p;//&p的结果是个指针,该指针的类型是p的类型加个*,在这里是int **。

该指针所指向的类型是p的类型,这里是int*。

该指针所指向的地址就是指针p自己的地址。

*ptr=&b;//*ptr是个指针,&b的结果也是个指针,且这两个指针的类型和所指向的类型是一样的,所以用&b来给*ptr赋值就是毫无问题的了。

**ptr=34;//*ptr的结果是ptr所指向的东西,在这里是一个指针,对这个指针再做一次*运算,结果就是一个int类型的变量。

指针表达式一个表达式的最后结果如果是一个指针,那么这个表达式就叫指针表式。

下面是一些指针表达式的例子:例六:inta,b;intarray[10];int*pa;pa=&a;//&a是一个指针表达式。

int**ptr=&pa;//&pa也是一个指针表达式。

*ptr=&b;//*ptr和&b都是指针表达式。

pa=array;pa++;//这也是指针表达式。

例七:char*arr[20];char**parr=arr;//如果把arr看作指针的话,arr也是指针表达式char*str;str=*parr;//*parr是指针表达式str=*(parr+1);//*(parr+1)是指针表达式str=*(parr+2);//*(parr+2)是指针表达式由于指针表达式的结果是一个指针,所以指针表达式也具有指针所具有的四个要素:指针的类型,指针所指向的类型,指针指向的内存区,指针自身占据的内存。

好了,当一个指针表达式的结果指针已经明确地具有了指针自身占据的内存的话,这个指针表达式就是一个左值,否则就不是一个左值。

在例七中,&a不是一个左值,因为它还没有占据明确的内存。

*ptr是一个左值,因为*ptr这个指针已经占据了内存,其实*ptr就是指针pa,既然pa已经在内存中有了自己的位置,那么*ptr当然也有了自己的位置。

数组和指针的关系如果对声明数组的语句不太明白的话,请参阅我前段时间贴出的文章<<如何理解c和c++的复杂类型声明>>。

数组的数组名其实可以看作一个指针。

看下例:例八:intarray[10]=,value;......value=array[0];//也可写成:value=*array;value=array[3];//也可写成:value=*(array+3);value=array[4];//也可写成:value=*(array+4);上例中,一般而言数组名array代表数组本身,类型是int[10],但如果把array看做指针的话,它指向数组的第0个单元,类型是int*,所指向的类型是数组单元的类型即int。

因此*array等于0就一点也不奇怪了。

同理,array+3是一个指向数组第3个单元的指针,所以*(array+3)等于3。

其它依此类推。

例九:char*str[3]={"Hello,thisisasample!","Hi,goodmorning.","Helloworld"};chars[80];strcpy(s,str[0]);//也可写成strcpy(s,*str);strcpy(s,str[1]);//也可写成strcpy(s,*(str+1));strcpy(s,str[2]);//也可写成strcpy(s,*(str+2));上例中,str是一个三单元的数组,该数组的每个单元都是一个指针,这些指针各指向一个字符串。

相关文档
最新文档