指针类型
字符指针
字符指针:指向字符型数据的指针变量。每个字符串在内存中都占用一段连续的存储空间,并有唯一确定的首地址。即将字符串的首地址赋值给字符指针,可让字符指针指向一个字符串。
例如:
char *str = "I am a student";
字符指针与字符数组的区别:
例如:
char *str = "I am a student";
char string[ ]="I am a student";
string是字符数组,存放的的字符串。可以改变数组元素的内容。str是一个变量,可以改变他的指向,但不能更改指向里面的内容。
例题:
#include<stdio.h>
#pragma warning(disable:4996)
int main() {
char str1[] = "hello world.";
char str2[] = "hello world.";
char* str3 = "hello world.";
char* str4 = "hello world.";
if (str1 == str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if (str3 == str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
system("pause");
return 0;
}
该代码输出为
解释:字符串常量只能被读取,不能被修改,倘如他们相同,只需生成一份。
这里str3和str4指str向的是一个常量字符串,会存储到单独的一个内存区域。当几个指针,指向同一个字符串的时候,他们实际上会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同。
数组指针和指针数组
int *a[4]; //指针数组
int (*p)[4]; //数组指针
指针数组就相当于一次声明了多个指针。数组的每一个元素都是一个指针。
数组指针指向的是数组,数组指针中存放的是数组的地址。
数组指针就相当于一次声明了一个指针。只不过这个指针指向很特别,是一个数组。
数组指针的用法
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9};
int(*p)[4]; //该语句是定义一个数组指针,指针步长为4个int即16位。
p = arr; //P指向为arr.
int i = 0;
while (i < 10)
{
printf("%d\t", (*p)[i]);
i++;
}
return 0;
}
指针数组的用法
int main() {
int i = 1, j = 2;
//p先跟[]结合,然后再跟*结合
int* p[2];//指针数组,存放指针的数组
p[0] = &i;
p[1] = &j;
printf("%d", sizeof(p));
return 0;
}
//数组p就两个元素,p[0]是指向i的指针p[1]是指向j的指针。
//这两个指针都是int型指针所以p是存放int型指针的数组。
//sizeof(p)返回数组占用的总空间,所以程序输出是8
数组传参与指针传参
//数组传参
int arr[10] = { 0 };
//把函数的参数名arr识别为*arr的指针,与其数组大小无关.
//所以数组大小的参数省略书写也是完全可以的。
void test1(int arr[])
//实参和形参变量的类型、大小都相同
void test2(int arr[10])
//编译器会把传入函数的数组参数隐式转化为指针*arr
//数组元素也会转换成数组的移动,
void test3(int *arr)
//指针数组传参
int *arr2[20] = { 0 };
void test2(int *arr[20])
//传参方式直观,实参与形参参数类型、大小均相同。
void test2(int **arr)
//可以把int*看作一个整体,将它typedef成为一个类型t
//那么实参中的数组定义就可以看成t arr2[20];了,
//调用函数传参就可以看成t *arr,
//所以指针数组可以当做二级指针来传参。
//一级指针传参
void print(int* p, int sz) {
int i = 0;
for (i = 0; i < sz; i++) {
printf("%d\n", *(p + i));
}
}
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10};
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
//一级指针,传给函数
print(p, sz);
return 0;
}
//二级指针传参
void test(int** ptr) {
printf("num=%d\n", **ptr);
}
int main() {
int n = 10;
int* p = &n;
int** pp = &p;
test(pp);
test(&p);
return 0;
}
函数指针
函数指针,其本质是一个指针变量,该指针指向这个函数。总结来说,函数指针就是指向函数的指针。
声明格式:类型说明符 (*函数名) (参数)
int (*fun)(int x,int y);
函数指针是需要把一个函数的地址赋值给它,有两种写法:
fun = &Function;
fun = Function;
函数指针数组
函数指针数组,就是每个元素都是函数指针的数组,直接在函数指针名后面加上数组符号[ ]即可。
函数指针数组的用途:转移表。
#include <stdio.h>
#pragma warning(disable:4996)
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
while (input)
{
printf("*************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf("*************************\n");
printf("请选择:");
scanf("%d", &input);
if ((input <= 4 && input >= 1))
{
printf("输入操作数:");
scanf("%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf("输入有误\n");
printf("ret = %d\n", ret);
}
return 0;
}
输出结果: