正确而灵活的运用指针可以有效的表达复杂的数据结构;能动态分配内存;能方便的使用字符串、数组。在调用函数的时候能获得多余1个的值,能直接处理内存地址等。
可以说不掌握指针就没掌握C的精华!
变量的指针就是变量的地址,存放变量地址的变量是指针变量,用来指向另一个变量
指针变量的定义:
基本类型 *指针变量名 如:
float * point_3 指向浮点变量的指针变量
char * point_4 指向字符类型的指针变量
指针变量只能存放地址。
一个简单的利用指针改变两个值的大小,和PHP思路基本相同,只是先把变量的地址赋给指针 在通过指针改变变量的值
#include <stdio.h>
main() {
int a,b;
int *point_1, *point_2 ,*p;
scanf("%d,%d",&a,&b);
point_1 = &a;
point_2 = &b;
if(a<b)
{
p = point_1;
point_1 = point_2;
point_2 = p;
}
printf("a=%d,b=%d\n",a,b);
printf("max=%d,min=%d",*point_1,*point_2);
}
注意:不能通过改变指针形参的值而是指针实参的值改变。
C语言中实参和形参的数据传递只是值传递,指针也要遵循这个规则。
函数调用只能返回一个值,运用指针变量做参数可以得到多个变化的值。
#include <stdio.h>
main()
{
void change(int *one,int *two,int *three);
int a,b,c;
int *one,*two,*three;
scanf("%d,%d,%d",&a,&b,&c);
one = &a;
two = &b;
three = &c;
change(one,two,three);
printf("max=%d,mid=%d,min=%d",a,b,c);
}
void change(int *one,int *two,int *three)
{
void ch(int *a,int *b);
if(*one<*two)
ch(one,two);
if(*one<*three)
ch(one,three);
if(*two<*three)
ch(two,three);
}
void ch(int *a,int *b)
{
int x;
x = *a;
*a = *b;
*b = x;
}
上面的是通过指针的方法,改变三个数由大到小排列。
数组指针:C语言规定数组名代表数组的首地址,也就是第0位元素的地址 如下:
p = &arr[0];
|| //相等
p = arr;
//设p的初始值为&a[0],则
//p+i就是a[i]的地址,或者说他们指向数组a的第i个元素。
p=&a[0];
p+i = a[i];
可以推得[]是变址运算符,即将a[i]按a+i计算地址,然后找出地址单元的值
如上:指向数组的指针变量也可以带下表 如:p[i] = *p(i)等价
根据以上叙述,引用一个数组元素可以用:
1。下标法 即a[i]的形式
2。指针发 即*(a+i)或*(p+i)。其中a是数组名p是指针变量,其初始值为p=a
下面是3种方法输出数组
1.数组下标法
#include <stdio.h>
main()
{
int g,arr[10]={1,2,3,4,5,6,7,8,9,10};
for(g=0;g<10;g++)
{
printf("%d",arr[g]);
}
}
2.通过数组名计算数组元素地址
#include <stdio.h>
main()
{
int g,arr[10]={1,2,3,4,5,6,7,8,9,10};
for(g=0;g<10;g++)
{
printf("%d",*(arr+g));
}
}
3.用指针变量指向数组元素
#include <stdio.h>
main()
{
int *g,arr[10]={1,2,3,4,5,6,7,8,9,10};
for(g=arr;g<(arr+10);g++)
{
printf("%d",*g);
}
}
上面3种方法第三种最快1和2的效率相同。C编译系统是将a[i]转化为*arr(g)处理的,即先计算元素地址,第3种方法不必重新计算地址,这样有效的改变(g++)能大大提高执行效率。
使用指针变量时要注意几点:
1.指针变量可以实现使本身的值改变
2.要注意指针变量的当前值 分析如下代码:
#include <stdio.h>
main()
{
int *g,arr[10],i;
g=arr;
for(i=0;i<10;i++)
{
scanf("%d ",g++);
}
printf("\n");
for(i=0;i<10;i++)
{
printf("%d",*g++);//先打印后++
}
}
为何输出的内容不是标准的内容 而是看似地址的内容?分析第一行代码可以推得G的地址逐个增加。
所以在循环结束后要使指针归位添加一行代码 --> g=arr;
用数组名作为函数参数:
从上面的学习中可以推断 用数组名做参数就是把数组的首地址传入函数。
下面做一个小例子
1.以数组名做参数
#include "stdio.h"
#define NUM 5
int main()
{
int i,arr[NUM]={2,4,8,5,6};
for(i=0;i<NUM;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
change(arr);
for(i=0;i<NUM;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
change(int arr[])
{
int mid = (NUM-1)/2;
int i,j,temp;
for(i=0;i<=mid;i++)
{
j = NUM-1-i;
temp = arr[i];
arr[i]= arr[j];
arr[j]= temp;
}
}
一段将字符串反转代码。下面以不同的参数形式实现相同的结果。