【本文链接】
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