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语言的灵活.......
希望对大家有帮助