C语言核心技术之指针

目录

一、地址与指针

二、指针变量赋值法

案例

三、引用指针变量

四、“&”和“*”运算符 

指针自加自减运算

五、常用的指针类型

字符型

指针数组:存放指针的数组

数组指针:指向数组的指针

实例

六、二维数组与指针

七、字符串与指针

八、字符串数组

九、指向指针的指针

十、返回指针值的函数

十一、本章实例

1. 编程实现将数组中的元素值按照相反顺序存放。

2. 输入两个字符串,将这两个字符串连接后输出。

3. 使用指针实现字符串的复制,并将字符串输出。


指针是C语言显著的优点之一,使用起来十分灵活而且能提高某些程序的效率,但是如果使用不当 则很容易造成系统错误。许多程序“挂死”往往都是由于错误地使用指针造成的。

一、地址与指针

系统的内存就好比是带有编号的小房间,如果想使用内存就需要得到房间号。

什么是地址?地址就是内存区中对每个字节的编号

 那指针是什么呢?

这里仅将指针看作是内存中的一个地址,多数情况下,这个地址是内存中另一 个变量的位置

 在程序中定义了一个变量,在进行编译时就会给该变量在内存中分配一个地址,通过访问这个地址可 以找到所需的变量,这个变量的地址称为该变量的“指针”

如上图地址1000是变量i的指针

变量i的地址是变量i和指针p二者之间连接的纽带

&i表示变量i的地址

“*”表示该变量是一个指针变量

二、指针变量赋值法

    //定义指针变量的同时就进行赋值
    int a;
    int *p=&a;
    //先定义指针变量,再赋值
    int a;
    int *p;
    p=&a;

        注意:不允许把一个数赋值给指针变量 

案例

#include<stdio.h>
main()
{
 int a, b;
 int *p1, *p2; /*声明两个指针变量*/
 scanf("%d,%d", &a, &b); /*输入两个数*/
 p1 = &a;
 p2 = &b; /*将地址赋给指针变量*/
 printf("The number is:%d,%d\n", *p1 , *p2);
}

三、引用指针变量

#include<stdio.h>
main()
{
 int *p,q;
 printf("please input:\n");
 scanf("%d",&q); /*输入一个整型数据*/
 p = &q;
 printf("the number is:\n");
 printf("%d\n",*p); /*输出变量的值*/
}

四、“&”和“*”运算符 

#include<stdio.h>
main()
{
 long i;
 long *p;
 printf("please input the number:\n");
 scanf("%ld",&i);
 p=&i;
 printf("the result1 is: %ld\n",&*p); //输出变量i的值
 printf("the result2 is: %ld\n",&i); //输出变量i的值

}

printf("&a:%d\n", &a);//&的作用是是返回操作数地址的单目运算符
printf("*p:%d\n", *p);//*的作用是返回指定的地址内的变量的值

程序运行结果如下图所示: 

 

指针自加自减运算

指针的自加自减运算不同于普通变量的自加自减运算,并非简单地加1减1

整形变量,指针p++;不是简单的在地址加一,而是指向下一个存放整型变量的地址

变量i是整形变量,所以执行P++后,p的值增加了4(4个字节)

 

 

短整型,执行p++后,p的值增加了2 

 

五、常用的指针类型

字符型

char ch='w';
char *pc=& ch;//pc指向字符变量
//把字符串第一个字符h的地址给p
//const char*p="hello world";

char *pc="hello world";//常量区

 "const char *”类型的值不能用于初始化"char *”类型的实体
//const修饰常量字符串时不可修改

    char str1[] = "he1lo world";
	char str2[] = "he1lo world";
	const char* str3 = "he1lo world";
	const char* str4 = "he1lo world";
	if (str1 == str2)
		printf("str1 == str2\n");
	else
		printf("str1 <> str2\n");
	if (str3 == str4)
		printf("str3 == str4\n");
	else
		printf("str3 <> str4\n");

 指针指向字符串首元素的地址

指针数组:存放指针的数组

	char* arr[5];//存放字符指针的数组
	int* arr2[4];//存放整型指针的数组

数组指针:指向数组的指针

	int arr[10] = { 0 ,1,2,3,4};
	int* p = arr;//数组首元素地址

这里arr是数组名,也就是数组的首地址,把它付给指针变量p,也就是 数组arr的首地址付给p

也可以如下形式

    int *p,arr[10];
    p=&arr[0];

实例

#include<stdio.h>
int main()
{
	int* p, * q, a[5], b[5];
	p = &a[0];
	q = b;
	printf("please input array a:\n");
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		scanf("%d", &a[i]);
	}
	printf("please input array b:\n");
	for (i = 0; i < 5; i++)
	{
		scanf("%d", &b[i]);
	}
	printf("\n");
	printf("array a is:\n");
	for (i = 0; i < 5; i++)
	{
		printf("%d ", *(p + i));
	}
	printf("\n");

	printf("array b is:\n");
	for (i = 0; i < 5; i++)
	{
		printf("%d ", *(q + i));
	}
	printf("\n");

	return 0;
}

 程序运行结果如下图所示: 

利用++运算可以把语句改为

	for (i = 0; i < 5; i++)
	{
		printf("%d ", *q++);
	}

 数组名是首元素地址的例外:

1、sizeof(数组名) 计算整个数组的大小/字节

2、&(数组名)         :取整个数组的地址

六、二维数组与指针

         &a[0][0]既可以看作二维数组的首地址,又可以看作数组0行0列的首地址

        a[0]+n表示第0行第n个元素的地址

示例如下

#include<stdio.h>
int main()
{
	int a[3][5] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },i,j;
	printf("array is :\n");
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			printf("%d ", *(a[i] + j));
		}
		printf("\n");
	}
	return 0;
}

 依然可以利用指针的++运算把语句改为

#include<stdio.h>
int main()
{
	int a[3][5] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },i,j;
	printf("array is :\n");
	int* p = a;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			printf("%d ", *p++);
		}
		printf("\n");
	}
	return 0;
}

七、字符串与指针

使用字符指针指向一个字符串

#include<stdio.h>
int main()
{
	char* string = "hello suryxin";
	printf("%s", string);
	return 0;
}

注意:只是把该字符串的第一个字符的地址赋给指针变量string

依旧等价于如下语句

char *string;
string="hello suryxin";

实例如下:

首先让指针指向两个数组的首元素字符的地址,然后把p1的值赋给p2,p1、p1 都加1,循环直到*p1的值为"\0"为止

#include<stdio.h>
int main()
{
	char str1[] = "hello suryxin";
	char str2[30], * p1, * p2;
	p1 = str1;
	p2 = str2;
	while (*p1 != '\0')
	{
		*p2 = *p1;
		p1++;
		p2++;
	}
	*p2 = '\0';
	puts(str2);
	return 0;

}

八、字符串数组

字符串数组是以字符串作为数组元素的数组

可以看成一个二位字符数组

#include<stdio.h>
int main()
{
	char str[3][20] = { "hello","suryxin","hhhaha" };
	for (int i = 0; i < 3; i++)
	{
		printf("%s\n", str[i]);
	}
	return 0;

}

九、指向指针的指针

 整型变量i的地址是&i,将其值传递给指针p1,即p1指向i;将p1的值传递给指针p2,即p2指向p1

p2就是所谓指向指针的指针

#include<stdio.h>
int main()
{
	int * * p;
	//定义一个指针变量p,指向另一个指针变量,该指针变量有指向一个基本整型变量
	//由指针运算符从右向左结合,所以等同于 int * (*p);
	return 0;
}

 实例:指向指针变量的指针变量的应用

#include<stdio.h>
int main()
{
	char *str[]= { "hello","suryxin","hhhaha" };
	char** p;
	for (int i = 0; i < 3; i++)
	{
		p = str + i;
		printf("%s\n", *p);
	}
	return 0;
}

 十、返回指针值的函数

int *fun(int x,int y)

实例:求长方形面积

使用返回值为指针的函数(自定义)

将指向长方形周长的变量的指针变量返回;

#include<stdio.h>
int* per(int a, int b);
int perimeter;
void main()
{
	int* iResult;
	iResult = per(100, 30);
	printf("iResult is:\n%d", *iResult);
}
int* per(int a, int b)
{
	int* p;
	p = &perimeter;
	perimeter = (a + b) * 2;
	return p;
}

 十一、本章实例

1. 编程实现将数组中的元素值按照相反顺序存放。

#include<stdio.h>
void main()
{
	int i, t, a[10];
	printf("please input:\n");
	for (i = 0; i < 10; i++)
		scanf("%d", &a[i]);
	printf("\nthe array is:\n");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	for (i = 0; i < 5; i++)
	{
		t = a[i];
		a[i] = a[9 - i];
		a[9 - i] = t;
	}
	printf("\n");
	printf("Now the array is:\n");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
}

2. 输入两个字符串,将这两个字符串连接后输出。

#include<stdio.h>
#include<string.h>
void main()
{
	char str1[60], str2[30];
	printf("please input string1:\n");
	gets(str1);
	printf("please input string2:\n");
	gets(str2);
	strcat(str1, str2);
	printf("the string1 is:\n");
	puts(str1);
}

3. 使用指针实现字符串的复制,并将字符串输出。

#include<stdio.h>
#include<string.h>
void main()
{
	char str1[30], str2[30];
	char* p1, * p2;
	p1 = str1;
	p2 = str2;
	printf("please input string1:\n");
	gets(str1);
	while (*p1 != '\0')
	{
		*p2 = *p1;
		p1++;
		p2++;
	}
	*p2 = '\0';
	printf("the string2 is:\n");
	puts(str2);
}

  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值