一、指针和数组的关系
1.
首先,我们需要知道指针虽然和数组有相同的访问方式,但是他们两个是分开的概念,完全没有关系。
#include <stdio.h>
#include <string.h>
#include <windows.h>#define N 10
int main()
{
char *str = "abcdef"; //str指针变量在栈上保存,“abcdef”在字符常量区,不可被修改
char arr[] = "abcdef"; //整个数组都在栈上保存,可以被修改,这部分可以局部测试一下
//1. 以指针的形式访问指针和以下标的形式访问指针
printf("以指针的形式访问指针和以下标的形式访问指针\n");
int len = strlen(str);
for (int i = 0; i < len; i++){
printf("%c\t", *(str + i));
printf("%c \n", str[i]);
}
printf("\n");
//2. 以指针的形式访问数组和以下标的形式访问数组
printf("以指针的形式访问数组和以下标的形式访问数组\n");
len = strlen(arr);
for (int i = 0; i < len; i++){
printf("%c\t", *(arr + i));
printf("%c \n", arr[i]);
}
printf("\n");
system("pause");
return 0;
}
结论:指针和数组指向或者表示一块空间的时候,访问方式是可以互通的,具有相似性。但是具有相似性,不代表是一个东 西或者具有相关性。
所以,C语言为什么要这么设计呢???
void InitArr(int *arr, int n)
{
for (int i = 0; i < n; i++){
*(arr + i) = i; //假设在这里只能以指针的形式访问
}
}int main()
{
int arr[N];
InitArr(arr, N);
for (int i = 0; i < N; i++){
printf("%d\n", arr[i]); //以数组的形式访问
}
system("pause");
return 0;
}
这样如果指针和数组元素访问没有打通的话,且存在大量的函数调用和数组传参的时候就要求程序员进行各种访问习惯的变化,提高了对程序员的要要求,且增加了出错的概率
2.指针数组和数组指针
到底哪个是指针数组,那个是数组指针呢??
(A)int *p1[10];
(B)int (*p2)[10];
这里需要弄清楚符号间优先级的问题,“[]”的优先级比“*”要高,所以p1与[]先结合构成一个数组的定义,数组位p1,int *修饰的是数组的内容,即数组的每个元素。也就是说数组p1包含10个指向int *类型数据的指针,就是指针数组。 ()的优先级比[]高,p2与*结合构成一个指针的定义,指针变量名为p2,指向10个int 修饰的数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。
接着在来看看一个小家伙(一个小细节)
虽然能编译通过但是会有告警
结论:数组元素个数,也是数组类型的一部分!
##地址的强转换
就好比我们在网上冲浪时看到一个瓜😎,先入为主的印象可能是坏的🤐(假设),然而在你了解过后发现这个人原来是一个很不错👍的人 ,所以说,不管你对于这个人的印象是好的还是坏的(类型),这个人是没有改变的(内容),是吧,他还是他。
结论:强制类型转化,改变的是对特定内容的看待方式,在C中,就是只改变其类型
3.多维数组和多级指针
二维数组的基本内存布局
#include <stdio.h>
#include <windows.h>
int main()
{
char a[3][4] = { 0 };
for (int i = 0; i < 3; i++){
for (int j = 0; j < 4; j++){
printf("a[%d][%d] : %p\n", i, j, &a[i][j]);
}
}
system("pause");
return 0;
}
结论:二维数组在内存地址空间排布上,也是线性连续且递增的。
数组的定义是:具有相同数据元素类型的集合,特征是,数组中可以保存任意类型。
那么数组中可以保存数组吗?答案是可以! 在理解上,我们甚至可以理解所有的数组都可以当成"一维数组"!
那么内部一维数组是在内存中布局是“线性连续且递增”的,多个该一维数组构成另一个“一维数组”,那么整体便也是线性连 续且递增的 这也就解释了,上述地址为何是连续的。
在强调一遍,我们认为:二维数组可以被看做内部元素是一维数组的一维数组 那么,三维呢?n维呢?
所以对于多为数组我们也可以看成一维数组来理解,来,让我们康康
来,这面有些题目,你们可以做做,不做也可以,我就放在这😎,嘿嘿,答案你们自己编译器运行,多动手是吧
接下来我们看看多级指针(🤫其实就二级)
这些知道吧?什么???不知道,不知道就赶紧看看第一篇
指针变量是变量吗? 是
变量有地址吗? 有
地址是数据吗? 是
数据可以被其他变量保存吗? 是
所以喽,保存一级指针就得用二级指针
#include <stdio.h>
#include <windows.h>
int main()
{
int a = 10;
int *p = &a;
int **pp = &p;
p = 100; //什么意思 p(左值)本来指向a,改成指向100
*p = 100; //什么意思 *p就是a嘛(直接了当),a=100嘛,so easy
pp = 100; //什么意思 pp本来指向p,改成指向100
*pp = 100; //什么意思 *pp就是p喽,就是p=100,和第一个是等价的,看得出来嘛??哈哈
**pp = 100; //什么意思 **pp咱们这么理解,*(*pp),*pp不就是p嘛,就是*p,那就是a喽
system("pause");
return 0;
}
看吧,二级指针也就这样,我们举一反三,多级指针也就这样洒洒水喽,自己悟吧,哈哈哈
4.数组参数和指针参数
首先来看看一维数组传参
#include <stdio.h>
#include <windows.h>void show(int a[10]) // int a[]这样也可以
{
printf("show: %d\n", sizeof(a));
}
//一维数组里的元素是可以忽略的哦
void show(int *a)
{
printf("show: %d\n", sizeof(a));
}//两种都是可以的
int main()
{
int a[10];
printf("main: %d\n", sizeof(a));
show(a);
system("pause");
return 0;
}
对于数组传参是要发生降维(不知道是啥??去看看别人怎么说,我说不清楚)的,降维成其内部元素类型的指针,这里描述的有点烂,写太久了,有点不想写了,哈哈哈,自己也是一知半解
再就是一级指针传参
不想写了,找张图你们看看😢,不写了,罢工了,太难写了,还有二级指针传参和二级数组传参啥的还有指针函数(这个虽然懂,但估计说不明白)
总结
没啦,开心