C语言指针详细知识(巨全巨详细)

1.什么是指针

定义及内涵

举例定义一个char* p,其类型是char* ,p用于存放一个char类型数据的地址,类似还有int* (存放整型数据的地址),double*(存放浮点型数据的地址) ,void* (可以存放任意类型数据的地址)。

&与指针的关系

&是一个操作符,比如定义一个整型int a=10;那么&a就取出了a的地址,即&a的类型是int* 。

int* p=&a,p中就存放了a的地址。

相反*意为解引用,*p = *(&a)= a =10  。

打印指针用%p 。

指针运算

定义一个数组int arr[5] = {1, 2, 3, 6, 9};

int* p=arr,则p指向第一个元素的地址(数组名也为数组首元素的地址),即*p = arr[0] = 1 ,       *(p+1)则代表向后移动,他表示arr[1],也就是2;于是*(p+4)- *p = 9 - 1 = 8;

于此不同的是    指针直接相减代表两个指针之间的元素个数(p+4)- p = 4;

学到这里我们就可以用指针来访问数组了

用指针打印一个数组:

#include <stdio.h>
int main() {
	int a[5] = { 1,2,3,4,5 };
	for (int i = 0; i < 5; i++) {
		printf("%d ", *(a + i));//a为首元素地址
		//等同于printf("%d ", a[i]);
	}
	return 0;
}

用指针将一个新闻标题字符串中的单词首字母大写,其余字母小写

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void title(char* x) {
	if (islower(*x))
		*x = *x - 32;
	for (int i = 1; i < strlen(a); i++) {
		if (isupper(*(x + i))) {
			*(x+i)=*(x+i)+32;
		}
	}
	for (int i = 1; i < strlen(a); i++) {
		if (*(x + i) == ' ') {
			*(x + i + 1) = *(x + i + 1) - 32;
		}
	}
}
int main() {
    char* a;
	a = (char*)malloc(6000 * sizeof(char));
    //分配空间,上两句等同于char a[6000];
	gets(a);
	title(a);
	printf("%s", a);
}

复杂多样的指针的类型

1 二级指针

char a = 'x';  char* p = &a;  char** pf = &p;

最后一个即为二级指针,是用于存放指针地址的。

有**pf = ‘x’;

2 指针数组

一个数组,其中每个元素皆为存放地址的指针。

举例:int* a[3]那么a[0],a[1],a[2]都为指针

数组指针表示二维数组

我们又知道,一个数组的名字也是一个指针(存放首元素的地址),我们就可以认为上例的a[0],a[1],a[2],都可以代表一个数组的名字,就可以有三个数组a[0][ ],a[1][ ],a[2][ ]。

类似的char* arr[2]可以表示二维数组arr[2][ ]。

#include <stdio.h>
#include <stdlib.h>
int main() {
	char* arr[3];
	for (int i = 0; i < 3; i++) {
		arr[i] = (char*)malloc(20);
	}//分配空间,上三行相当于char arr[2][20]
	for (int i = 0; i < 3; i++) {
		scanf("%s", arr[i]);
	}
	for (int i = 0; i < 3; i++) {
		printf("%s\n", arr[i]);
	}
}

3 字符指针变量

我们知道了字符指针char* 还有一种特殊的用法如下

int main()
{
const char* p = "hello point."; //这⾥是把⼀个字符串放到p指针变量⾥了吗?
printf("%s\n", p);
return 0;
}

打印结果应为hello point,实际是将字符串的首元素’h‘的地址放在p中

4 数组指针变量

存放数组的地址,能够指向数组的指针变量

举例int (*p)[10];        (注意与指针数组区分,int* p[10]是指针数组)

p是数组指针变量,指向一个数组。

5 函数指针变量

整形和字符型有存放的地址,一个函数也有存放它的地址。

void test()
{
printf("hehe\n");
}
void (*pf1)() = &test;
//或者void (*pf2)()= test;
int Add(int x, int y)
{
return x+y;
}
int(*pf3)(int, int) = Add;
//或者int(*pf3)(int x, int y) = &Add;
//此时pf3(2,3) = (*pf)(2,3) = add(2,3) = 5

6 函数指针数组

存放函数指针的数组,可以理解为存放函数的数组

举例定义:int (*p[3])(int x)  定义了一个函数数组,共3个函数,返回值皆为int,皆需要一个整型参数。

实例运用

1 转移表

int add(int x, int y) {
	return x + y;
}
int sub(int x, int y) {
	return x - y;
}
int mul(int x, int y) {
	return x * y;
}
int div(int x, int y) {
	return x / y;
}

int main() {
	int input = 0;
	int (*p[5])(int x, int y) = { 0,add,sub,mul,div };
	int x, y, ret;
	do {
		printf("**************************************\n");
		printf("****************1.add ****************\n");
		printf("****************2.sub ****************\n");
		printf("****************3.mul ****************\n");
		printf("****************4.div ****************\n");
		printf("****************0.exit****************\n");
		printf("**************************************\n");
		printf("请输入计算法  ");
		scanf("%d", &input);
		if (input >= 1 && input <= 4) {
			printf("输入操作数  ");
			scanf("%d%d", &x, &y);
			ret = (*p[input])(x, y);
			printf("%d\n", ret);
		}
		else if (input == 0) {
			printf("退出");
		}
		else {
			printf("输入错误,请重新输入");
		}
	} while (input);

	return 0;
}

主要是函数指针数组的运用,方便了许多。

2 回调函数

int add(int x, int y) {
	return x + y;
}
int sub(int x, int y) {
	return x - y;
}
int mul(int x, int y) {
	return x * y;
}
int div(int x, int y) {
	return x / y;
}
void calc(int(*pf)(int, int))
{
int ret = 0;
int x, y;
printf("输⼊操作数:");
scanf("%d %d", &x, &y);
ret = pf(x, y);
printf("ret = %d\n", ret);
}
int main(){
calc(add);
calc(sub);
}

这样的运用让我们感受的c语言的灵活.......

希望对大家有帮助

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值