指针 指向一维数组 二维数组 字符数组 返回值为地址 指向函数的指针 指针数组 常量指针

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaoxiao20121314/article/details/54023319

在谈论指针之前,先讲一下文件包含#include命令,通常有两种形式#include<>和#include“ ”两种形式。二者有何区别呢?使用尖括号的形式:系统不搜索包含文件所在的目录,直接在指定的路径中搜索;使用双引号的形式,系统先在包含目录中搜索,找不到时会在指定目录中搜索。说的简单一点就是自己定义的头文件要使用双引号的形式,在这里还要说明一点,文件包含命令可以包含任意一种格式的文件,eg:#include  "mine.txt"

讲过文件包含命令我们言归正传,讲解一下令人费解的指针。首先要声明一点指针是一个变量,与数值变量不同的是指针变量用于存储变量的地址。指针变量的定义,数据类型 * 指针变量名;eg:int *p1,*p2;//定义两个指针变量。在C语言中要求指针变量要存储同类型的变量地址,同类型的指针变量之间可以相互赋值,eg:int *p,a;//这里p是指针变量,a是int型的普通数值变量

float b;//定义变量b 在这里指针变量可以指向a的内存地址但不能指向b的地址。eg:p=&a;(正确)p=&b;(错误)在这里还要声明一点指针变量本身实占用内存单元的,我们可利用printf来输出指针变量的内存地址。eg:

#include <stdio.h>

void main()

{

int *p,*p1,a=10;//定义两个指针变量和一个整形变量

p=&a;//令p指向a的内存地址

p1=p;//将p1指向p的地址,p内存中存放着a的地址

       // 以上三句话可以简化为int a,*p=&a,p1=p;

printf("输出p和p1所指内存中所放的数值");

printf("p-%d\np1-%d\na-%d\n",*p,*p1,a);

printf("输出p、p1和a的内存地址");

printf("p--%p,p1__%p,a--%p",&p,&p1,&a);

}

进过运行我们可以看见,p1,p都指向了a的地址,并将a的值输出,同时可以看见三者在内存中的存储地址并不相同,由三者都是自动变量,所以每次运行程序为之分配的地址可能都与上次的地址不同。讲解了指针的一般定义和一些小的注意事项后,我们来一起看看指针的应用和形式。

一、指针指向一维数组(同样指针的数据类型要与数组的数据类型相同)


#include <stdio.h>
void main()
{
int *p, i,a[10] = { 0 };
for (i = 0; i < 10; i++)
{
scanf_s("%d", &a[i]);//在vs2013中的格式,在vc++6.0中的等价语句为scanf(%d", &a[i]);
}
printf("原数组");
for (i = 0; i < 10;i++)
printf("%d\t", a[i]);
p = a;//将p指向数组的首地址,等价于p=&a[0];
printf("\n");//输出换行
printf("使用指针输出数组");
for (i = 0; i < 10; i++)
{
printf("%d\t", *(p + i));//使用指针输出数组元素,通过此语句可以看出指针变量可以与常数进行运算,表示偏移几个元素当两个指针变量直接相减表示二者之间的元素个数
}
}
二、指针指向二维数组


#include <stdio.h>
void main()
{
int(*p)[3], i, j, a[3][3] = { 0 };
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3;j++)
scanf_s("%d", &a[i][j]);
}
printf("原数组");
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
printf("%d\t", a[i][j]);
}
p = a;//将p指向数组的首地址,等价于p=&a[0][0];
printf("\n");//输出换行
printf("使用指针输出数组");
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
printf("%d\t", *(*(p + i)+j));//使用指针输出数组元素
}
p = a;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
printf("%d\t", p[i][j]);
}

三、指针指向字符数组与字符串指针


#include <stdio.h>
void main()
{
char s[10] = "I LOVE C!";
char *p = s,i;//也可以直接利用字符串为指针变量赋初值eg:char *p="I Love Learning C!"
for (i = 0; s[i] != '\0'; ++i)
printf("%c", s[i]);
//printf("%s", *p);%s格式控制符不能输出含有空格的字符串
puts(p);//puts函数可以输出含有空格的字符串,并自动换行;等价于puts(s)
}

四、函数返回值为指针


#include <stdio.h>


int *sum(int *a, int *b)
{
*a = *a+*b;
return a;//这里的不能使用局部变量的地址作为返回值eg错误的形式如下:

//int *c;*c= *a+*b;return c;c为局部地址函数调用后c的地址被回收
}


void main()
{
int *add, a = 10, b = 20;
add=sum(&a, &b);
printf("%d", *add);
}

五、指向函数的指针


#include <stdio.h>


int sum(int a, int b)
{
a = a+b;
return a;
}


void main()
{
int c, a = 10, b = 20;
int(*add)(int a, int b);
add = sum;//函数名为函数的入口地址
c = (*add)(a, b);
printf("%d", c);
}

六、指针数组

#include <stdio.h>


void main()
{
char *p[3];
char s[3][20] = { "I love learning!", "c is useful", "study hardly" };//定义字符串数组并初始化
p[0] = s[0];
p[1] = s[1];
p[2] = s[2];
puts(p[0]);
puts(p[1]);
puts(p[2]);
}

此外还要提一下常量指针和指向常量的指针,常量指针表示指针指向的地址是固定的,不能更改定义形式为:int *const p=&a;一定初始化就不能再指向其他变量。指向常量的指针为指针可以指向其他变量,但被指向的变量的之不可被改变,定义形式为 const int *p=&a;//a的值在程序执行过程中不可被改变,但p可以指向其他变量。至现常量的常量指针,故名思议指针所指向的变量和变量的地址都不能改变,定义形式:const int *const p=&a;//a的值不可再被改变,p也不能在指向其他变量。

猜你喜欢

转载自blog.csdn.net/xiaoxiao20121314/article/details/54023319