`
kofsky
  • 浏览: 201679 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

C语言的指针

阅读更多

<!----><o:p></o:p> 

1.     指针<o:p></o:p>

指针包括两个方面的内容:<o:p></o:p>

  • 指针指向的对象,即指针变量的值,也就是数据对象存放的地址<o:p></o:p>
  • 指针的类型,指针的类型决定了该怎么去解释其指向的对象区域,同一片内存区域,按照不同的解释,其意义是完全不同<o:p></o:p>

指针本身也是一个对象,也占据内存空间。

<o:p></o:p> 

这是 The C Programming Language 里面的示意图,c is a char and p is a pointer that points to it.<o:p></o:p>

<!----><v:shapetype o:spt="75" coordsize="21600,21600" filled="f" stroked="f" id="_x0000_t75" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" o:connecttype="rect" gradientshapeok="t"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style="WIDTH: 414.75pt; HEIGHT: 67.5pt"><v:imagedata src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image001.png" o:title=""></v:imagedata></v:shape><o:p></o:p>

分清楚指针与指针指向的对象意义重大。<o:p></o:p>

有几个常见的错误。<o:p></o:p>

<o:p> </o:p>

错误1.没有为指针指向的对象分配内存

  1. char *str;
  2. gets(str); // 错误,没有为str分配内存, str指向垃圾数据

当定义一个指针变量

char *str时,只是在栈上分配了str的空间,指针的值则是未定义的,也就是了垃圾。<o:p></o:p>

下面的才是正确的:

  1.     char *str;
  2.     str = (char*)malloc(100);// 申请一片内存区,让str指向这片区域
  3.     gets(str); // ok

事实上,上面的代码再作一个内存申请是否成功的检测:

If( str != NULL ) 就更好了。<o:p></o:p>

<o:p> </o:p>

错误2. 野指针问题<o:p></o:p>

指针使用完毕后,一般会free 释放其指向的内存区域,但释放完毕以后,此时指针的值是存在的,只不过是垃圾值。用 if( p != NULL ) 会返回真。<o:p></o:p>

比较好的习惯是,free掉以后显式设置 p = NULL<o:p></o:p>

<o:p> </o:p>

错误3.同一片内存区域 多次释放<o:p></o:p>

这类错误一般隐藏的比较深。尤其在C++里,呵。<o:p></o:p>

比如<o:p></o:p>

  1.     char *p1 =  (char*)malloc(100);
  2.     char *p2 = p1; // 两个指针指向同一片内存区域
  3.     free(p1);     
  4.     free(p2);     // 错误!前一个语句已经释放内存;
  5.     // 晕死,用MinGW测试这段代码居然没问题,靠

 

C++的指针比 C 语言的指针要复杂许多,因为有许多内存的自动申请与释放,还有继承关系,交叉在一起,头疼。<o:p></o:p>

<o:p> </o:p>

指针相加毫无意义,相减表示两个指针中间的元素个数。<o:p></o:p>

<o:p> </o:p>

指针占用空间:地址总线32位时,指针占四个字节。Int* p1;Char* p2;Char (*p3)[10];<o:p></o:p>

Sizeof P1,p2,p3的大小会是一样的。但是其指向的对象迥异<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

2.    指针与数组<o:p></o:p>

     

       数组与指针是不同的。数组名对应着(不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。数组名是常量,因而不能修改。比如int m[10], m++是一个编译错误。定义一个指针n指向m第一个元素,int *n = m, 此时n++合法,表达式执行完毕后n指向数组第2个元素。另外,用sizeof(m) sizeof(n) 会是完全不同的结果。sizeof(m)返回的是整个数组的长度,sizeof(n)则是指针的长度。<o:p></o:p>

<o:p> </o:p>

表达式a[i]会自动被转换成*(a+i)参与运算,因此使用指针形式并不会比数组形式更有效率。另外,&a[i]a+i也是等价的。下标总是和指针的偏移量相同<o:p></o:p>

<o:p> </o:p><o:p> </o:p>

将数组作为参数传到函数中时,数组形式与指针形式等价。数组名被编译器当作指向该数组第一个元素的指针。<o:p></o:p>

Fun ( int *arr ){···}<o:p></o:p>

fun ( int arr [] ){···}<o:p></o:p>

fun ( int arr[10] ){···}//这里实参是多大的数组都可以<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>字符串常量初始化指针与数组(The C Programming Language P104)<o:p></o:p>

There is an important difference between these definitions: <o:p></o:p>

   char amessage[] = "now is the time"; /* an array */<o:p></o:p>

   char *pmessage = "now is the time"; /* a pointer *

 

   amessage is an array, just big enough to hold the sequence of characters and '\0' that initializes it. Individual characters within the array may be changed but amessage will always refer to the same storage. On the other hand, pmessage is a pointer, initialized to point to a string constant; the pointer may subsequently be modified to point elsewhere, but the result is undefined if you try to modify the string contents.<o:p></o:p>

<o:p> </o:p>

<v:shape id="_x0000_i1028" type="#_x0000_t75" style="WIDTH: 357pt; HEIGHT: 109.5pt"><v:imagedata src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image003.png" o:title=""></v:imagedata></v:shape><o:p></o:p>

<o:p> </o:p>

3.    数组指针与指针数组<o:p></o:p>

数组指针:指向数组的指针<o:p></o:p>

指针数组:指针构成的数组<o:p></o:p>

<o:p> </o:p>

char a[100];        
char (*p)[100] = &a; <o:p></o:p>

// 这里b就是一个数组指针,它指向整个数组,数组包含100char<o:p></o:p>

<o:p> </o:p>

int matrix[3][10];<o:p></o:p>
int (*mm)[10] = matrix;<o:p></o:p>
// 这也是一个数组指针,指向matrix的第一行, 这个数组包含10个整形元素<o:p></o:p>
<o:p> </o:p>典型的指针数组定义如下:<o:p></o:p>
char *a[10]; // 数组,包含10个元素,每个元素都是指向char的指针<o:p></o:p>
比如:<o:p></o:p>
char *name[] = { "Illegal month", "Jan", "Feb", "Mar" };<o:p></o:p>

<o:p> </o:p>

(The C Programming Language P112)<o:p></o:p>

The parentheses are necessary since brackets [] have higher precedence than *. Without parentheses, the declaration  int *daytab[13] is an array of 13 pointers to integers.<o:p></o:p>

<o:p> </o:p>

4.     指针数组与二维数组(The C Programming Language P114)<o:p></o:p>

char *name[] = { "Illegal month", "Jan", "Feb", "Mar" };
<o:p></o:p>

<v:shape id="_x0000_i1026" type="#_x0000_t75" style="WIDTH: 240.75pt; HEIGHT: 126.75pt"><v:imagedata src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image005.png" o:title=""></v:imagedata></v:shape><o:p></o:p>

char aname[][15] = { "Illegal month", "Jan", "Feb", "Mar" };
<o:p></o:p> 

5.    函数指针<o:p></o:p>

int *p1();
int (*p2)();
p1是一个函数,它返回一个指向int* 型数据的指针。
p2是一个函数指针,它指向一个参数为空的函数,这个函数返回一个整数数据<o:p></o:p>

<o:p> </o:p>

(The C Programming Language P120)<o:p></o:p>

int (*comp)(void *, void *)<o:p></o:p>

which says that comp is a pointer to a function that has two void * arguments and returns an int. <o:p></o:p>

The use of comp in the line <o:p></o:p>

   if ((*comp)(v[i], v[left]) < 0)<o:p></o:p>

is consistent with the declaration: comp is a pointer to a function, *comp is the function, and <o:p></o:p>

   (*comp)(v[i], v[left])<o:p></o:p>

is the call to it. The parentheses are needed so the components are correctly associated; without them, <o:p></o:p>

   int *comp(void *, void *)    /* WRONG */<o:p></o:p>

says that comp is a function returning a pointer to an int, which is very different.<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

分享到:
评论

相关推荐

    C语言指针练习填空和阅读程序题

    C语言指针练习填空和阅读程序题 本资源主要涵盖了C语言指针的相关知识点,包括指针的基本概念、指针运算、指针与数组的关系、指针与字符串的关系等。通过本资源的学习,可以帮助读者更好地理解和掌握C语言指针的...

    c语言指针c语言指针c语言指针c语言指针c语言指针

    c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针...

    彻底搞定C语言指针————

    "彻底搞定C语言指针" C语言指针是C语言中一个非常重要的概念,但它却是初学者最容易迷惑和混淆的部分。要真正搞定C语言指针,需要深入理解C语言变量的存储实质和内存空间的概念。 1. 变量的存储实质 内存空间可以...

    c语言指针学习笔记

    本文将介绍C语言指针的基本概念、定义、初始化、运算以及与一维数组的关系。 首先,我们要理解内存地址的概念。在程序运行时,操作系统为代码和数据分配内存空间,每一个内存单元都有一个唯一的编号,称为内存地址...

    C语言指针函数和函数指针详细介绍.

    C语言指针函数和函数指针详细介绍 C语言中指针函数和函数指针是两个不同的概念,但它们之间存在着紧密的联系。本文将对C语言中的指针函数和函数指针进行详细的介绍。 一、指针函数 指针函数是指返回值为指针的...

    C语言指针详解.zip

    c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 ...

    C语言指针课程PPT

    【C语言指针课程PPT】讲解了C语言中核心的指针概念,它是C语言高效编程的关键。指针允许程序直接访问内存地址,增强了代码的灵活性和性能。以下是关于指针的详细知识点: 1. **变量与内存地址**: - 当在C语言中...

    c语言指针详解,10分钟学会指针用法

    C语言指针详解 C语言指针是一种关键的数据类型,想要学好C语言就必须掌握指针的用法。本篇文章将详细介绍C语言指针的基本概念、指针的声明和使用、数组指针的加减运算、指针之间的运算、指针之间的大小比较、数组...

    C语言指针和汇编语言间接寻址的关系探讨_从存储空间图的视角加以分析.

    在探讨C语言指针与汇编语言间接寻址的关系时,我们从存储空间图的视角出发,这不仅能帮助我们更直观地理解这两种编程语言中数据访问机制的本质,还能揭示它们之间深层次的联系。 ### 存储空间图的概念 存储空间图...

    指针详解——介绍C语言指针,看过这个,笔试无忧

    《指针详解——C语言指针完全解析》 在C语言的世界中,指针是一个强大的工具,也是理解和掌握C语言的关键。本文将深入探讨指针的概念、类型、运算及其在笔试中的重要性。 首先,我们要了解什么是指针。指针是一个...

    C语言指针,进阶学习,有一定学习基础

    本节将针对“C语言指针”的进阶学习进行详细阐述。 首先,指针的本质是一个存储内存地址的变量。当你创建一个变量时,系统会在内存中为该变量分配一块空间,而指针就是保存这块空间地址的变量。在C语言中,声明指针...

    《C语言指针详细讲解》.ppt

    本教程《C语言指针详细讲解》深入探讨了指针的使用,包括指针与数组、指针与字符串以及指针与函数的交互。 首先,我们来看指针的概念。在C语言中,每当我们声明一个变量,系统就会在内存中为这个变量分配一块空间,...

    C语言指针的详细资料(英文和中文)

    通过深入学习这些知识点,你将能够熟练地运用C语言指针进行高效的编程,解决复杂的算法问题,并构建自己的数据结构。提供的《C和指针》PDF文档将为你提供详细的解释和实例,加深对这些概念的理解。

    《C语言指针经验总结》PDF

    《C语言指针经验总结》PDF是一份深入探讨C语言指针使用技巧和实践经验的文档。C语言中的指针是其强大特性的核心之一,它允许程序员直接操作内存,实现高效的数据处理和灵活的程序设计。这份资料通过实例和经验分享,...

    C语言指针详解(让你不再惧怕指针)

    在C语言中,指针是其核心特性之一,也是许多高级功能实现的基础。指针能够直接存储内存地址,使得...通过《C语言指针详解》这样的资料,你可以系统地学习和巩固这些知识,消除对指针的畏惧,成为一名更出色的C程序员。

    精选C语言指针资料大全

    "精选C语言指针资料大全"集合了多种资源,旨在帮助初学者和深入研究者更好地理解和掌握这一核心概念。以下是对这些资源中可能包含的知识点的详细解释。 1. **C指针宝典**: - 指针基础:理解指针是什么,如何声明...

    C语言指针题库

    C语言指针题库 本资源摘要信息是关于C语言指针的题库,涵盖了计算机等级二级考试中的相关内容。该资源包含选择题和编程题,旨在帮助考生和学习者提高C语言指针的知识和技能。 指针基本概念 在C语言中,指针是一种...

    C语言 指针学习的笔记

    《C语言指针学习笔记》 指针是C语言中的一种强大特性,它允许程序员直接操作内存地址,实现高效的数据处理和复杂的程序设计。要掌握指针,我们需要理解其四方面的核心概念:指针的类型、指针所指向的类型、指针的值...

    C语言指针题目相关(附参考答案).docx

    C语言指针题目相关 在本文档中,我们将从多个角度来讨论C语言中的指针概念,并通过实践题目来巩固相关知识。以下是提炼出的知识点: 1. 指针的定义和声明: 在C语言中,指针是指向内存中某个存储单元的变量。指针...

Global site tag (gtag.js) - Google Analytics