前言
今天来较为深入的介绍一下指针,希望大家能有所收获~
那么,先进行一些简单的基础知识复习吧。
字符指针
格式:char *
补充:
表达式“abcdef”的值是首字符a的地址
所以当像下面这么使用时,它的含义是:
char *pc = “abcde”
pc存储的是a的地址
printf(“%s”, p);
打印出的abcde
提示:
此处可以理解为将abcde存储在一个数组里面,数组名就是首元素地址
那么由此可以引出一个比较少见的写法:
输出的是c
注意
因为字符串“abcde”是常量,不可改变,但是,p作为指针变量是可以改变的,这时候改变p指向的对象程序就会报错。
所以最后在*左边加上const,使p指向的对象不可改变
一道题:
看下面这段代码:
问:输出结果是什么
#include <stdio.h> int main() { char str1[] = "hello bit."; char str2[] = "hello bit."; const char* str3 = "hello bit."; const char* str4 = "hello bit."; 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"); return 0; }
运行结果:
知识点:
当两个常量数组相同时,只会储存一份,
所以,虽然创建了两个变量,但存储的是同一个地址(同一个值)
图解:
指针数组
定义:存放指针的数组
用途:
可以用指针数组模拟一个二维数组
如下:
int main() { int arr1[] = { 1,2,3,4,5 }; int arr2[] = { 2,3,4,5,6 }; int arr3[] = { 3,4,5,6,7 }; int* arr[] = { arr1, arr2, arr3 }; int i = 0; return 0; }
数组指针
定义:指向数组的指针
格式(唯一):
存储元素的类型 (*p)[数组大小] = &arr
注意:要明确指定出数组的大小,如果不写就默认为0,程序会报错。
但数组指针的使用不常见,
因为当对数组指针进行解引用后,就是数组名,多此一举。
就算使用,也大多用于二维数组,下面举个例子
void print(int (*p)[5], int r, int c) { int i = 0; for (i = 0; i < 3; i++) { int j = 0; for (j = 0; j < 5; j++) { printf("%d ", p[i][j]); } printf("\n"); } } int main() { int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} }; print(arr, 3, 5); return 0; }
此处数组名指向的是二维数组的第一行
这里传递的 arr,也就是第一行的地址,是一维数组的地址
此处用数组指针来接收。
旧识新知
数组名指的是首元素的地址,
但有两个例外
1.sizeof(数组名)此处指的是整个数组
2.&数组名
取出的是数组的地址
那么创建一个变量存储数组的地址,他就是数组的指针,简称数组指针
但是 此处需要注意区分数组名和取地址数组名,虽然在打印时二者是一样的,但在运算时,因为 &arr 表示的是 数组的地址 ,所以它是以整个数组大小去运算的,而不是数组中首元素的大小
示例如下:
#include <stdio.h> int main() { int arr[10] = { 0 }; printf("arr = %p\n", arr); printf("&arr= %p\n", &arr); printf("arr+1 = %p\n", arr+1); printf("&arr+1= %p\n", &arr+1); return 0; }
运行结果:
这样就能直观的看出二者的区别
一组辨析
大家可以思考一下下面几行的代码的含义是什么
int arr[5]; int *parr1[10]; int (*parr2)[10]; int (*parr3[10])[5];
解释: