c/c++指针总结[pointer summary]

【本文链接】

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

    str2[0] = ‘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);

    return 0;
}

(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)

{
    int i = 0;

     header = (LinkNode *)malloc(sizeof(LinkNode));

     header->Elem = 10;

     header->next = NULL;
}

int main()
{

     LinkNode *head = NULL;

     CreateList(head);

    if(head != NULL)

         printf("%d\n", head->Elem);

     free(head);

    return 0;
}

/*

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)

{
    int i = 0;

     (*header) = (LinkNode *)malloc(sizeof(LinkNode));

     (*header)->Elem = 10;

     (*header)->next = NULL;

}

int main()
{

     LinkNode *head = NULL;

     CreateList(&head);

    if(head != NULL)

         printf("%d\n", head->Elem);

    free(head);

    return 0;
}

/*

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)

{
    for(int i = 0; i < nLength; i++)

     {

        // modify content of *pointer

        Arr[i] += i + 20;
     }
}

int main()

{
    int nArr[5] = {0};
    int  i;

     printf("Before:\n");
    for(i = 0; i < 5; i++)

         printf("%d  ", nArr[i]);

    //0 0  0  0  0



     Trans(nArr, 5);

     printf("\nAfter\n");
    for(i = 0; i < 5; i++)

         printf("%d  ", nArr[i]);

    // 20  21  22  23  24

    return 0;
}

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
    int a[2][3] = {1, 2, 3, 4, 5, 6};
    int (*p)[3];

     p = a;

    // test sizeof
    // for a

    cout << sizeof(a) << endl; // 24
    cout << sizeof(a + 0) << endl; // 4  (24 in debug local watch)

    cout << sizeof(a + 1) << endl; // 4  (24 in debug local watch)



     cout << sizeof(a[0]) << endl; // 12
    cout << sizeof(a[1]) << endl; // 12
    cout << sizeof(*(a + 0)) << endl; // 12
    cout << sizeof(*(a + 1)) << endl; // 12
    cout << sizeof(a[0][0]) << endl; // 4

    // for p
    cout << sizeof(p) << endl; // 4
    cout << sizeof(p + 0) << endl; // 4
    cout << sizeof(p + 1) << endl; // 4

     cout << sizeof(p[0]) << endl; // 12
    cout << sizeof(p[1]) << endl; // 12
    cout << sizeof(*(p + 0)) << endl; // 12
    cout << sizeof(*(p + 1)) << endl; // 12
    cout << sizeof(p[0][0]) << endl; // 4

    return 0;
}

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)

{
    int nTotal = 0;
    for(int i = 0; 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));

    return 0;
}

【本文链接】

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

c/c++指针总结[pointer summary],布布扣,bubuko.com

时间: 2024-10-26 21:41:30

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

【C++】智能指针(Smart Pointer)

1. 传统指针存在的问题 传统指针存在诸多的问题,比如指针所指向的对象的生命周期问题,挂起引用(dangling references),以及内存泄露(memory leaks). 如下是一个传统指针的使用过程 void Foo() { int *iPtr = new int[5]; // manipulate the memory block // ... // ... // ... delete[] iPtr; } 以上代码将正常运行且内存将被合理释放,但是使用指针常会发生一些意想不到的事情

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

我们已经知道在C++中,对象变量直接存储的是对象的值.这是与Java不同的,在Java中对象变量存储的是一个地址,该地址指向对象值实际存储的地方.有时在C++中也需要实现这样的布置,这就用到了指针pointer.在 C++中,一个指向对象的变量叫做指针.如果T是一种数据类型,则 T* 是指向这种数据类型的指针. 这里重点介绍C++与Java的不同,要详细了解C++中指针的使用 就像 Java中一样,一个指针变量可以被初始化为空值 NULL,另外一个指针变量的值,或者一个调用new生成的新对象:

智能指针(smart pointer)(2):unique_ptr

Unique pointer: Manages the storage of a pointer, providing a limited garbage-collection facility, with little to no overhead over built-in pointers (depending on the deleter used). These objects have the ability of taking ownership of a pointer: onc

智能指针(smart pointer)(1):auto_ptr

智能指针解决了资源生存期管理的问题(尤其是动态分配的对象).智能指针有各种不同的风格.多数都有一种共同的关键特性:自动资源管理.这种特性可能以不同的方式出现:如动态分配对象的生存期控制,和获取及释放资源 (文件, 网络连接).这里主要讨论第一种情况,它们保存指向动态分配对象的指针,并在正确的时候删除这些对象. 何时我们需要智能指针? 有三种典型的情况适合使用智能指针: ? 资源所有权的共享 ? 要写异常安全的代码时 ? 避免常见的错误,如资源泄漏 共享所有权,当多个对象需要同时使用第三个对象的情

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

首先本文是对参考中三个连接的博客进行的整理,非常感谢三位博主的努力,每次都感叹网友的力量实在太强大了…… 第一章 快速上手 1.  在C语言中用/*和*/来注释掉这段代码,这个实际上并不是十分的安全,要从逻辑上删除一段C代码,最好的办法是使用#if指令: #if 0 Statement #endif 2.  其他语言中,无返回值的函数称为过程(procedure). 3.  数组做参数的时候是以引用(reference)的方式传递的,即地址传递.而标量和常量都是传值调用,被调用的函数无法修改调用

指针(pointer)的使用

1.变量的指针和指针的变量 变量的指针:变量的存储地址, 指针变量:存储指针的变量 2.指针变量的基本符号 &:取地址符号 *:间接取址符号 NULL||0:初始化 **:多级指针 *p[]:指针数组 3.程序实例(自己 尝试写类函数,一直不懂啥时候才定义变量位为private 1 //*m:定义指针变量 &m:取m的地址 *&m:间接访问 m的内容 2 //&和 *互为逆运算 3 4 #include <iostream> 5 #include<stdl

(转)Delphi2009初体验 - 语言篇 - 智能指针(Smart Pointer)的实现

快速导航 一. 回顾历史二. 智能指针简介三. Delphi中的interface四. Delphi中智能指针的实现五. interface + 泛型 = 强类型的智能指针!六. 智能指针与集合七. 注意事项八. 总结 本随笔所有源代码打包下载 一.回顾历史 在c++中,对象可以创建在栈里,也可以创建在堆里.如: class CTestClass{public: CTestClass() { printf("Create"); } void DoPrint() {} ~CTestCla

函数指针(pointer to function)——qsort函数应用实例

一,举例应用 在ACM比赛中常使用 stdlib.h 中自带的 qsort 函数,是教科书式的函数指针应用示范. #include <stdio.h> #include <stdlib.h> int comp(const void*a, const void*b) { return *(int*)a - *(int*)b; } int main() { int n = 5; int *array = (int*)malloc(n*sizeof(int)); int i = 0; f

C/C++学习笔记--指针(Pointer)

定义指针 一般类型: type_name  *  var_name; 例如: int _var = 1555; int * _var_addr=&_var; 一般类型数组类:type_name * var_names=new type_name[SIZE]