【本文链接】

http://www.cnblogs.com/hellogiser/p/pointer-summary.html

1.指针注意事项

(1). 指针类型字符串不容许修改

char *str1=”abcd”; char str2[]=”abcd”;的区别。指针类型的字符串一般不允许修改,如:str1[0]=’c’;这样的语句会导致运行时错误。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
void test_string()
{
    char *str1 = "abcd";
    char str2[] = "1234";

cout << str1 << endl; // abcd
    cout << str2 << endl; // 1234
    cout << *str1 << endl; // a
    cout << *str2 << endl; // 1

//str1[0]='X'; // ERROR
] = 'Y'; // right
    cout << *str2 << endl; // Y
}

(2).指针/数组作为参数进行传递

在C语言中,参数是使用值传递的。 int func(int a );当调用者调用该函数的时候将传递一个值给a,这个a只是你传递进去的参数的一个副本。而数组传递的时候,会退化为指针,其将数组的首地址复制给形参。看下面的一个例子。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/3
*/
void fun(char str[])
{
    printf("After transform:%d\n", sizeof(str));  //4
}
int main()
{
    char strs[] = "abcdefg";
    printf("Before transform:%d\n", sizeof(strs)); //8
    fun(strs);
    ;
}

(3). 在函数内部修改指针本身(无效)vs修改指针指向的内容(OK)

许多初学C指针的同学想在函数内部修改作为参数传递进来的指针的值。看以下代码:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/3
*/
#include "stdafx.h"
#include <iostream>
using namespace std;

typedef struct Link_Node
{
    int Elem;
    struct Link_Node *next;
} LinkNode, *PLinkList;

void CreateList(LinkNode *header)
{
    ;
    header = (LinkNode *)malloc(sizeof(LinkNode));
    header->Elem = ;
    header->next = NULL;
}

int main()
{
    LinkNode *head = NULL;
    CreateList(head);
    if(head != NULL)
        printf("%d\n", head->Elem);
    free(head);
    ;
}

/*
A: head---0
---CreateList---
B: header---0
C: NODE
B: header---C
---CreateList---
A: head---0
*/

此做法无效,在函数内部修改header的地址,函数结束后回到main函数,head仍然是null。

我们可以修改其指向的变量的值,而不能修改指针本身的内容了。为了能够修改指针本身的内容,我们需要传递指针本身的地址。所以在上面那例中,需要传递head指针本身的地址。代码如下:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/3
*/
#include "stdafx.h"
#include <iostream>
using namespace std;

typedef struct Link_Node
{
    int Elem;
    struct Link_Node *next;
} LinkNode, *PLinkList;

void CreateList(LinkNode **header)
{
    ;
    (*header) = (LinkNode *)malloc(sizeof(LinkNode));
    (*header)->Elem = ;
    (*header)->next = NULL;
}

int main()
{
    LinkNode *head = NULL;
    CreateList(&head);
    if(head != NULL)
        printf("%d\n", head->Elem);
    free(head);
    ;
}

/*
A: head---0
---CreateList---
B: header---A
C: NODE
A: head---C
B: header---A
---CreateList---
A: head---C
*/

下面我们再看一例,在函数内部修改指针指向的内容。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/3
*/
#include "stdafx.h"
#include <iostream>
using namespace std;
void Trans(int *Arr, int nLength)
{
    ; i < nLength; i++)
    {
        // modify content of *pointer
;
    }
}

int main()
{
    };
    int  i;
    printf("Before:\n");
    ; i++)
        printf("%d  ", nArr[i]);
    //0 0  0  0  0

Trans(nArr, );
    printf("\nAfter\n");
    ; i++)
        printf("%d  ", nArr[i]);
    // 20  21  22  23  24
;
}

http://blog.csdn.net/gamecreating/article/details/5382711

http://www.cnblogs.com/nezha/p/3204410.html

2. 指针vs数组

数组名不是变量!指针是变量!

数组名仅仅是一个符号,不是变量,它没有自己的存储空间,而指针是个变量,有自己的空间。

C标准有一条:当数组出现在函数的参数中时,无论是形参还是实参,都转换为指针再进行操作。

http://blog.jobbole.com/44863/

3. 指针的指针

http://blog.jobbole.com/60647/

4. 数组指针vs指针数组

http://blog.csdn.net/touch_2011/article/details/6966980

http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html

简单举例说明:

int *p[2]; 首先声明了一个数组,数组的元素是int型的指针。

int (*p)[2]; 声明了一个指针, 指向了一个有两个int元素的数组。(数组指针,也称行指针)

其实这两种写法主要是因为运算符的优先级, 因为[]的优先级比*高。所以第一种写法,p先和[]结合,所以是一个数组,后与*结合,是指针。后一种写法同理。

指针数组如下处理就会很清楚: typedef int* intPtr; intPtr p[2]; 一目了然,所以为了避免迷惑,做适当的typedef也是很有必要的。

同理,数组指针也可以作类似处理: typedef int intArray2[2]; intArray2 * p; 和原来的声明都是等价的。

数组指针(也称行指针)

定义 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=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。

如要将二维数组赋给一指针数组:

int *p[3];

int a[3][4];

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]

优先级:()>[]>*

sizeof分析

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/3
*/
int _tmain(int argc, _TCHAR *argv[])
{
    // array pointer
};
    ];
    p = a;

// test sizeof
    // for a
    cout << sizeof(a) << endl; // 24
) << endl; // 4  (24 in debug local watch)
) << endl; // 4  (24 in debug local watch)

cout << ]) << endl; // 12
]) << endl; // 12
)) << endl; // 12
)) << endl; // 12
]) << endl; // 4

// for p
    cout << sizeof(p) << endl; // 4
) << endl; // 4
) << endl; // 4

cout << ]) << endl; // 12
]) << endl; // 12
)) << endl; // 12
)) << endl; // 12
]) << endl; // 4

;
}

5. 函数指针

http://www.cnblogs.com/nezha/p/3204410.html

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/3
*/
typedef int (*func)(char a[], int nLength);

int total(char a[], int nLength)
{
    ;
    ; i < nLength; ++i)
        nTotal += a[i];
    return nTotal;
}

int main()
{
    char a[] = "abcde";
    int nLength = strlen(a);
    func fp;
    fp = total;
    printf("%d\n", fp(a, nLength));
    ;
}

【本文链接】

http://www.cnblogs.com/hellogiser/p/pointer-summary.html

c/c++指针总结[pointer summary]的更多相关文章

  1. c/c++ 标准库 智能指针( smart pointer ) 是啥玩意儿

    标准库 智能指针( smart pointer ) 是啥玩意儿 一,为什么有智能指针??? c++程序员需要自己善后自己动态开辟的内存,一旦忘了释放,内存就泄露. 智能指针可以帮助程序员"自 ...

  2. C 指针(pointer)

    C 指针(pointer) /* * pointer.c * 指针在C中的应用 * */ #include <stdio.h> int main(void) { /* * i是一个int类 ...

  3. 指针锁定 Pointer Lock API 用法

    指针锁定 Pointer Lock API 通过它可以访问原始的鼠标运动(基于指针的相对位移 movementX / movementY),把鼠标事件的目标锁定到一个特定的元素,同时隐藏视图中的指针光 ...

  4. 《C和指针(Pointer on c)》 学习笔记(转自:http://dsqiu.iteye.com/blog/1687944)

    首先本文是对参考中三个连接的博客进行的整理,非常感谢三位博主的努力,每次都感叹网友的力量实在太强大了…… 第一章 快速上手 1.  在C语言中用/*和*/来注释掉这段代码,这个实际上并不是十分的安全, ...

  5. 《C和指针(Pointer on c)》 学习笔记

    转载:http://dsqiu.iteye.com/blog/1687944 首先本文是对参考中三个连接的博客进行的整理,非常感谢三位博主的努力,每次都感叹网友的力量实在太强大了…… 第一章 快速上手 ...

  6. C++中Reference与指针(Pointer)的使用对比

    整理日: 2015年3月18日 引用(reference)和指针(pointer)是学C++过程中最令人头疼的问题,常常不知道什么时候用哪个合适,又常常弄混.找到Dan Saks的这篇文章,讲的很清楚 ...

  7. A pointer is a variable whose value is the address of another variable 指针 null pointer 空指针 内存地址0 空指针检验

    小结: 1.指针的实际值为代表内存地址的16进制数: 2.不同指针的区别是他们指向的变量.常量的类型: https://www.tutorialspoint.com/cprogramming/c_po ...

  8. 野指针(Wild pointer)和悬垂指针(dangling pointer)

    详细参考如下: Dangling pointer(悬垂指针.迷途指针)和 Wild pointer(野指针) 迷途指针经常出现在混杂使用malloc() 和 free() 库调用: 当指针指向的内存释 ...

  9. 浅析指针(pointer)与引用(reference)

    在c++函数中,形式参数用引用和用指针都可以起到在被调用函数中改变调用函数的变量的作用.什么时候用引用作参数?什么时候用指针作参数呢 void function (int *ptr); void fu ...

随机推荐

  1. VS2013打开项目提示此版本的应用程序不支持其项目类型(.csproj)

    命令行或者Vs自带的命令提示符输入: devenv.exe /resetskippkgs 重新打开项目即可.

  2. 【USACO1.1】Broken Necklace

    题意 一个环形项链,有rbw三种珠子,r代表red,b代表blue,w代表white,从任意一个位置断开,两端分别取珠子,同一端取的珠子要相同颜色,w可以染成想要的颜色,即既可当作r也可以当作b,求最 ...

  3. cowboy-高性能简洁的erlang版web框架

    那么Cowboy是什么呢? Cowboy is a small, fast and modular HTTP server written in Erlang. 其定位非常明确: Cowboy aim ...

  4. this的使用

    1.使用this调用本类中的属性 class Person{ private String name; private int age; public Person(String name,int a ...

  5. mybatis-spring从1.1升级到1.2所带来的dao层级的编写问题

    我们公司的项目使用spring+mybatis组合.所以就必须得使用mybatis-spring了.所以此处就昨日mybatis-spring从1.1升级到1.2所带来的dao层级的编写问题,做了一个 ...

  6. ubuntu 12.04 server + OPENACS(TR069)安装配置日记

    1. 有两个叫openacs的, openacs.org下的不是 2. 严格匹配版本:luo@bogon:~$ ls jboss-4.2.3.GA-jdk6.zip  jdk-6u41-linux-i ...

  7. jQuery的查找

    children([expr])概述 :取得一个包含匹配的元素集合中每一个元素的所有子元素的元素集合.可以通过可选的表达式来过滤所匹配的子元素.注意:parents()将查找所有祖辈元素,而child ...

  8. UVA 1626 Brackets sequence(括号匹配 + 区间DP)

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/E 题意:添加最少的括号,让每个括号都能匹配并输出 分析:dp ...

  9. TOJ3540Consumer(有依赖的背包)

    http://acm.tju.edu.cn/toj/showp3540.html3540.   Consumer Time Limit: 2.0 Seconds   Memory Limit: 655 ...

  10. MyEclipse------在特定目录创建文件和书写内容

    readwrite.jsp <%@ page language="java" import="java.util.*" pageEncoding=&quo ...