文档库 最新最全的文档下载
当前位置:文档库 › C语言指针加强学习

C语言指针加强学习

C语言指针加强学习
C语言指针加强学习

C语言指针的相关概念

1、基础概念

在C语言里,基本变量存放的是数据,而指针变量是存放地址的变量(另一变量额地址)。在C语言中,指针也称之为地址,所以我们常说某某变量的指针,可以理解为某某变量的在内存中的地址。如:b变量的指针是1000,可以理解为b在内存中的地址是1000,注意不能理解为b的指针变量是1000(错误的理解)。

2、定义指针变量

在c语言指针的定义形式如下:

类型说明符*指针变量名

如:

int*p1,*p2;

//错误的定义方式

int*p1,p2;//p1整形指针,p2是整形变量

在c里,可以在变量前加&符号取得变量的地址,同样地,可以在指针变量前加*符号取得指针变量指向的变量的值(该内存地址上存放的数据),如:

int a=4;

int*p=&a;

printf("指针p指向的变量的值是%d\r\n",*p);//注意在这行代码里,p是指针,*p是指向的变量的值。

3、指针变量作为函数参数

//带有指针变量的函数定义形式如下

void fun(int*p1,int*p2)

//调用方式如下:

int*ptr1=&a1;

int*ptr2=&a2;

fun(ptr1,ptr2)

注:在被调用函数中,试图修改指针变量的值(即地址)来达到改变实参的目的都是错误的。

这句话如何理解呢?这里牵涉到一个比较容易混淆的问题-值传递和引用传递的区别。在这里提供一种理解方式,如下:将实参传给形参的时候,形参都是将实参的内容复制一遍,再调用相对应的函数。

void swap1(int num1,int num2){

int temp=num1;

num1=num2;

num2=temp;

}

void swap2(int*num1,int*num2){

//试图修改指针变量的值(地址)

int*temp=num1;

num1=num2;

num2=temp;

}

void swap3(int*num1,int*num2){

int temp=*num1;

*num1=*num2;

*num2=temp;

}

int main(){

int a=1,b=2;

int*ptr1=&a,*ptr2=&b;

swap1(a,b);//结果不变:a=1,b=2

swap2(ptr1,ptr2);//结果不变,a=1,b=2

swap3(ptr1,ptr2);//a=2,b=1

}

4、字符串与指针

字符串是字符的集合,可以使用数组(指针常量)或指针变量来表示。

char*str1="tianya";

char str2[]="tianya";

在上面代码中:str1是一个指针变量,str2是指针常量,所以str2不能使用++或--运算符。输入对应字符串的值如下:

printf("str1的值为%s\n",str1);

printf("str2的值为%s\n",str2);

另外,我们还需要理解一下,下面这几个的定义方式的不同:

char*str="tianya";

char str[]="tianya";

char str[10]="tianya";

char str[2]="tianya";

C++Primer Plus第6版中文版清晰有书签PDF+源代码

https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101227.htm

读C++Primer之构造函数陷阱https://www.wendangku.net/doc/506283306.html,/Linux/2011-08/40176.htm

读C++Primer之智能指针https://www.wendangku.net/doc/506283306.html,/Linux/2011-08/40177.htm

读C++Primer之句柄类https://www.wendangku.net/doc/506283306.html,/Linux/2011-08/40175.htm

将C语言梳理一下,分布在以下10个章节中:

Linux-C成长之路(一):Linux下C编程概要

https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242.htm

Linux-C成长之路(二):基本数据类型https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242p2.htm Linux-C成长之路(三):基本IO函数操作

https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242p3.htm

Linux-C成长之路(四):运算符https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242p4.htm Linux-C成长之路(五):控制流https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242p5.htm Linux-C成长之路(六):函数要义https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242p6.htm Linux-C成长之路(七):数组与指针https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242p7.htm Linux-C成长之路(八):存储类/动态内存

https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242p8.htm

Linux-C成长之路(九):复合数据类型https://www.wendangku.net/doc/506283306.html,/Linux/2014-05/101242p9.htm Linux-C成长之路(十):其他高级议题

5、一维数组和指针

数组与指针,是一个比较容易让人迷惑的地方,最主要就是各种不同的表示方式所代表的不同的含义,下面我们一步步来理解一下不同的方式:

1)定义方式:

int a[5];//a其实是一个常量指针,指向数组的第一个元素a[0]

int*p=a;//等效于:int*p=&a[0];

2)通过指针引用数组元素

int a[5]={10,20,30,40,50};

int*p=a;//或int*p=&a[0];

printf("the seconde elem is%d\n",a[1]);//20

printf("the seconde elem is%d\n",*(a+1));//20

printf("the seconde elem is%d\n",p[1]);//20

printf("the seconde elem is%d\n",*(p+1));//20

类似地推算,我们可以知道:a[i]等同于*(a+i),当中a[0]等同于*a或*(a+0);*(p+i)等同于ptr[i]。看过一些书,会有着这样一种介绍*和[]等同,结合前面的例子,我们再看另外一个例子:

int a[5]={10,20,30,40,50};

int*p=a;//或int*p=&a[0];

printf("the seconde elem is%d\n",a[1]+1);//21

printf("the seconde elem is%d\n",*a+1);//11,可以看成(*a)+1或*(a+0)+1

printf("the seconde elem is%d\n",p[1]+1);//21

printf("the seconde elem is%d\n",*p+1);//11,可以看成(*p)+1或*(p+0)+1

是不是觉得我们基本可以了解这些使用了,我们再深入地学习一下,当*与++或——相遇时,又会是一种什么样的情况:

//第一种情况

int a[5]={10,20,30,40,50};

int*p=a;//或int*p=&a[0];

printf("*p++=%d\n",*p++);//10,可以看成是*(p++)

//第二种情况:

int a[5]={10,20,30,40,50};

int*p=a;//或int*p=&a[0];

printf("*++p=%d\n",*++p);//20,可以看成*(++p)

//第三种情况

int a[5]={10,20,30,40,50};

int*p=a;//或int*p=&a[0];

printf("++*p=%d\n",++*p);//11,可以看成++(*p)

*与++或--的运算符优先级相同,结合性是由右往左。如果觉得基本都懂的,那猜猜一下下面这个例子会输出什么?

int a[5]={10,20,30,40,50};

int*p=a;//或int*p=&a[0];

printf("*p++=%d\n",*p++);

printf("*++p=%d\n",*++p);

printf("++*p=%d\n",++*p);

现在的我们可以来总结一下:

当p=&a[i]时,则有:

*p++相当于a[i++];

*++p相当于a[++i];

*p--相当于a[i--];

*—p相当于a[—i];

C语言指针教程

一、指针是什么?

指针也是一个变量,但是这个变量存储的是一个地址,指向一个存储单元。我们可以根据指针(地址)找到他所指的变量,并对这个变量进行操作(赋值等)。通过C里面的取地址符号&和取所指内容的符号*可以很方便的表示指针以及指针所指的变量之间的关系。

二、为什么要用指针?

为什么要用指针?指针能够带来哪些好处?以下内容引用课本上的内容:

“正确而灵活的应用的指针,可以有效的表示复杂的数据结构;能够动态的分配内存;方便的使用字符串;有效而方便的使用数组;在调用函数时获得一个以上结果;能直接处理内存单元地址等”

以上的概括应该算是比较完整的,但是对于初学C的人可能又会理解起来很抽象(可能都理解不了什么是数据结构);我们尝试从最简单的-----“在调用函数时获得一个以上结果”来看看指针的作用。

1》值传递:C中在函数调用时始终采取“值传递”的方式。意思是这样的:并不是实

参直接参与了函数(参加了函数内的各类操作),只是实参把他的值传递给形参去参与函数,完成函数内的操作(函数调用时形参被分配了内存,形参的值是实参的拷贝;但要明白,形参和实参不是一个变量,不占用相同的内存,形参发生变化了实参不一定变化。就好比三个变量a,b,c执行了步骤:b=a;b=c后,a不一定等于c)

例1:请看下面的代码。代码是要实现两个数(a,b)的交换,于是构造了交换函数swap;但是能完成目的吗?

例2:那么怎么办呢?应用指针。理解下面的程序,他能很好的完成数字交换的工作。

这里面可能有同学会疑问“为什么这样就可以?这里函数调用也是值传递啊”。

对。这里也是值传递;但是在swap里面,是根据指针对所指向的变量进行了操控,(可以给他起个名字-----上帝之手)你心里要明白,我们在函数调用时,不是x和y互相交换了,而是通过这两个指针,对他们所指的内容(即a,b本身)进行了调换。

例3:如果你理解了以上我所说的,再看看下面这段代码,他能完成任务吗?

怎么样?是不是有点糊涂。我来帮你理理思路。就算你用指针做函数参数,函数调用依旧是值传递的。例2中,x,y指向a,b,通过*x,*y就可以改变a,b;例3中,x,y指向a,b,swap交换了x,y;可这对主函数里的c,d指针以及变量a,b没有带来任何改变。

相关文档