| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1045 人关注过本帖
标题:指针资料整理
只看楼主 加入收藏
flyingcloude
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:6
帖 子:598
专家分:1512
注 册:2008-1-13
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:9 
指针资料整理
这些天经常碰到指针的问题,故花了些时间整理下。如发现有错误,欢迎各位拍砖。

指针在应用中的各种类型:
(1)  int *ip;  //(char* cp,float* fp,double* dp)  一级指针变量
(2)  int **ip;  //(char** cp,float** fp,double** dp) 二级指针变量
(3)  const int* ip;  //常量指针
(4)  int* const ip;  //指针常量
(5)  const int* const icp; //常量指针常量
(6)  int *ip[10];   //指针数组
(7)  int (*ip)[10]; //数组指针
(8)  int *f(int a); //char* copy(char* s1, char* s2)  指针函数
(9)  int (*gp)(int);  //函数指针
(10) int (*gp[10])(int); //函数指针的数组
下面针对这11中情况作一一解说
(1)  int *ip;  //(char* cp,float* fp,double* dp)  一级指针变量
一级指针是我们接触最多,也是最简单的指针。
#include <iostream>
using namespace std;
int main(void)
{
    char *p = "hello world";
    int i = 0;
    while(p[i] != '\0')
        cout << p[i++];
    cout << '\n';
   
    int *ip, iq;
    iq = 5;
    ip = &iq;
}
上面程序体现了二个问题:1)指针的增减运算 2)定义指针一个*只能修饰一个指针
    指针的增减是以该类型的实体大小为单位的(但对指针作乘除是没有意义的)
        对char指针加 1 实际增加了1个字节
         对float指针加 1 实际增加了4个字节
        对int指针加 1 实际增加了4个字节
   定义指针一个*只能修饰一个指针
        程序中的 ip是一个指针,而iq是一个整数变量
  在很多c/c++程序,指针跟数组进行替换使用,这样以使得我们觉得指针跟数值是等价,但是数组跟指针还是有很大区别的,请看下面的例子。
#include <iostream>
using namespace std;
void fun(char a[100])
{
    cout << sizeof(a) << '\n';  //4
}
int main(void)
{
    char a[] = "hello world";
    a[0] = 'Y';
    char *p = "welcome to c++";
//    p[0] = 'X'; //编译器不能发现该错误,但是运行时出错
    cout << sizeof(a) << '\n';  //12
    cout << sizeof(p) << '\n';  //4
    fun(a);   
}
    看了上面的例子之后,我们来说说数组跟指针的区别:
     数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。
      指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。指针远比数组灵活,但也更危险。
      字符数组 a 的容量是 12 个字符,其内容为 hello world\0。a 的内容可以改变,如 a[0]= ‘Y’。指针 p 指向常量字符串“welcome to c++”,(位于静态存储区,内容为 welcome to c++\0) ,
     常量字符串的内容是不可以被修改的。从语法上看,编译器并不觉得语句 p[0]= ‘X’有什么不妥,但是该语句企图修改常量字符串的内容而导致运行错误,
     所以我们经常把char *p = "welcome to c++" 写成 const char *p = "welcome to c++",这样就能够使得 p[0] = 'X'语句在编译的时候就报错。
     sizeof(a)的大小是12(注意别忘了\0) sizeof(p)是一个指针的大小,当把数组作为函数参数进行传递时,数组自动退化为指针。
指针参数如何传递内存的?
#include <iostream>
#include <string.h>
using namespace std;
char* getStr1()
{
    char a[] = "hello world";
    return a;
}
char* getStr2()
{
    char *a = new char[12];
    strcpy(a, "hello world");
    return a;
}
char* getStr3()
{
    char *a = "hello world";
    return a;
}
void getStr4(char *p, int num)
{
    p = new char[num];
    strcpy(p, "hello world");
}
void getStr5(char **p,int num)
{
    *p = new char[num];
    strcpy(*p, "hello world");
}
int main(void)
{
    cout << "getStr1 " << getStr1() << '\n';
   
    char *str2 = NULL;
    str2 = getStr2();
    cout << "getStr2 " << str2 << '\n';
    str2[0] = 'X';
    cout << "getStr2 " << str2 << '\n';
    delete [] str2;
    char *str3 = NULL;
    str3 = getStr3();
    cout << "getStr3 " << str3 << '\n';
//    str3[0] = 'X';  //编译通过,但运行出错
   
    char *str4 = NULL;
    int num = 50;
    getStr4(str4, num);
    cout << "getStr4 " << (str4 == NULL?"NULL": str4) << '\n';
   
    char *str5 = NULL;
    getStr5(&str5, num);
    cout << "getStr5 " << str5 << '\n';
}
getStr1()输出的是乱码,因为在getStr1()里return的是栈内存,所以当退出函数之后,char a[]也随着被清除了。
getStr2()能够正确运行。
getStr3()虽然能够正确运行,但是不管在什么地方返回都是常量数据
getStr4()运行结束后,str4仍然还是NULL,因为char *p参数在getStr4()函数运行结束后随着也被清除了
getStr5()能够正确运行。
(2)  int **ip;  //(char** cp,float** fp,double** dp) 二级指针变量
    二级指针变量与一级指针变量的关系,跟二维数组与一维数组的关系有些类似,在这就不多说了

(3)  const int* ip;  //常量指针
(4)  int* const ip;  //指针常量
(5)  const int* const icp; //常量指针常量
    这3个有一些相似性,看如下例子。
#include <iostream>
using namespace std;
int main(void)
{
        const int a = 10;
        int b = 5;
        int c = 13;
        const int *ip = &a;
        int* const cp = &b;
        const int* const icp = &c;
        *ip = 30; //错误,常量指针不能修改指向的常量,*ip只能做右值
        ip = &c; //正确,指针本身能够改变
        *cp = 50; //正确,指针常量,指针所指向的值能够修改
        cp = &c; //错误,指针常量本身不能够改变
        *icp = 50;//错误,常量指针常量不能修改指向的常量
        icp = &c; //错误,常量指针常量不能够改变指针本身
}
(6)  int *ip[10];   //指针数组
(7)  int (*ip)[10]; //数组指针
    指针数组:顾名思义,就是说的首先是一个数组吧,然后数组的元素是指针而已
    数组指针:指向一个数组的指针
#include <iostream>
using namespace std;
int main()
{
        int a = 5, b = 1, c = 10;
        int *p1 = &a, *p2 = &b, *p3 = &c;
        int *p[3] = {p1, p2, p3}; //指针数组,数组中的每个元素都是一个指针
        for(int i = 0; i < 3; i++)
                cout << *p[i] << '\n';
        int (*ap)[3];       //数组指针
        int arr[4][3] = {{1,2},{2,3},{3}};
        ap = arr;
        for(int i = 0; i < 4; i++)
        {
                for(int j = 0; j < sizeof(ap[i])/sizeof(int); j++)
                        cout << ap[i][j] << " ";
                cout << '\n';
        }
}
(8)  int *f(int a); //char* copy(char* s1, char* s2)  指针函数
    指针函数是指函数返回值是一个指针类型
    如我们在c语言中经常使用strcpy就是这样一个函数
    char* strcpy(char* Dest, const char* Src)
    {   
        assert(Dest != NULL &&Src !=NULL);
        char* tmp = Dest;
        while((*Dest++ = *Src++) != '\0');
        return tmp;
    }
    看到这函数,我们可能会觉得为什么要有一个返回值呢?不是把Src的内容都已经复制到Dest中了么,这个主要是为了完成了链式运算,为了是strcpy函数能够作右值。
(9)  int (*gp)(int);  //函数指针
(10) int (*gp[10])(int); //函数指针的数组
#include <iostream>
using namespace std;
void fun1(){ cout << "good" << '\n';}
void fun2(){ cout << "better" << '\n';}
void fun3(){ cout << "best" << '\n';}

int main()
{
        void (*gp)() = fun1; //函数指针
        gp();
        void (*gpa[3])();//函数指针数组
        gpa[0] = fun1;
        gpa[1] = fun2;
        gpa[2] = fun3;
        for(int i = 0; i < 3; i++)
                gpa[i]();
}
收到的鲜花
  • qlc002009-11-02 13:05 送鲜花  5朵   附言:好文章
搜索更多相关主题的帖子: 资料 指针 
2009-11-01 15:37
qlc00
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:2
帖 子:157
专家分:540
注 册:2007-11-26
收藏
得分:8 
顶一下版主!

Anything is possible!
2009-11-01 16:17
ds0807
Rank: 1
等 级:新手上路
帖 子:3
专家分:6
注 册:2009-9-27
收藏
得分:6 
谢谢
2009-11-02 22:20
lulu86
Rank: 1
等 级:新手上路
帖 子:7
专家分:6
注 册:2009-11-3
收藏
得分:6 
谢了!
2009-11-03 22:41
loricheung
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2009-9-26
收藏
得分:0 
感谢版主!!
2009-11-04 10:34
forclwy
Rank: 4
等 级:业余侠客
帖 子:167
专家分:255
注 册:2008-10-21
收藏
得分:0 
必须顶了……
2009-11-04 21:28
huangyan6611
Rank: 1
等 级:新手上路
帖 子:33
专家分:0
注 册:2009-4-29
收藏
得分:0 
BZ好样的啊
2009-11-06 09:20
kobe09204
Rank: 2
等 级:论坛游民
帖 子:5
专家分:10
注 册:2009-11-8
收藏
得分:0 
版主牛!
2009-11-09 16:15
nishimywife
Rank: 1
等 级:新手上路
帖 子:13
专家分:6
注 册:2009-11-8
收藏
得分:0 
写的很好,你能不能帮我把<<这个问题怎样解决>>,就是哪个5*5的举阵的代码写下来啊,谢谢,
2009-11-10 11:58
blowing00
Rank: 1
等 级:新手上路
帖 子:12
专家分:2
注 册:2009-11-9
收藏
得分:0 
很棒!谢谢版主!
2009-11-10 13:43
快速回复:指针资料整理
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018983 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved