网站线上推广方案,网站从哪里找的,深圳招聘网站,icp备案管理系统目录 1、数组名理解
2、一维数组传参本质
3、二级指针
4、指针数组和数组指针
5、函数指针变量 1、数组名理解
首先来看一段代码#xff1a;
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };printf(%d\n, sizeof(arr));return 0;
}
输出的结果是…目录 1、数组名理解
2、一维数组传参本质
3、二级指针
4、指针数组和数组指针
5、函数指针变量 1、数组名理解
首先来看一段代码
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };printf(%d\n, sizeof(arr));return 0;
}
输出的结果是40如果arr是数组首元素的地址那输出应该是4/8才对。
其实数组名就是数组首元素第一个元素的地址是对的但是有两个例外
sizeof数组名。sizeof中单独放数组名这里的数组表示整个数组计算的是整个数组的大小单位是字节数组名。这里的数组名表示整个数组取出的是整个数组的地址不是首元素的地址。
除此之外任何地方使用数组名数组名都表示首元素的地址。
再来看一段代码
#include stdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };printf(arr[0] %p\n, arr[0]);printf(arr[0]1 %p\n, arr[0] 1);printf(arr %p\n, arr);printf(arr1 %p\n, arr 1);printf(arr %p\n, arr);printf(arr1 %p\n, arr 1);return 0;
}
输出结果 这里我们发现arr[0]和arr[0]1相差4个字节arr和arr1相差4个字节是因为arr[0]和 arr 都是首元素的地址1就是跳过1个元素。
但是arr 和 arr 1 相差40个字节这就是因为arr是数组的地址1 操作是跳过整个数组的。
2、一维数组传参本质
先看一段代码
#include stdio.h
void test(int arr[])
{int sz2 sizeof(arr) / sizeof(arr[0]);printf(sz2 %d\n, sz2);
}
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int sz1 sizeof(arr) / sizeof(arr[0]);printf(sz1 %d\n, sz1);test(arr);return 0;
}
输出结果 在数组传参的时候传递的是数组名也就是说本质上数组传参本质上传递的是数组首元素的地址。所以函数形参的部分理论上应该使用指针变量来接受首元素的地址。
3、二级指针
假设有下面的声明
int zippo[4][2];//内含int数组的数组
因为zippo是数组首元素的地址所以zippo的值和zippo[0]相同。而zippo[0]本身是一个内含两个整数的数组所以zippo[0]的值和它首元素一个整数的地址即zippo[0][0]的值相同。简而言之zippo[0]是一个占用一个int大小对象的地址。所以zippo和zippo[0]的值相同。给指针或地址加1其值会增加对应类型大小的值。在这方面zippo和zippo[0]不同因为zippo指向的对象占用了两个int大小而zippo[0]指向的对象只占用一个int大小。因此zippo1和zippo[0]1的值不同。zippo[0]是该数组首元素zippo[0][0]的地址所以 *zippo[0]表示存储在zippo[0][0]上的值。与此类似*zippo代表该数组首元素zippo[0]的值但是zippo[0]本身是一个int类型值的地址。该值的地址是zippo[0][0]。所以*zippo就是zippo[0][0]。**zippo与*zippo[0][0]等价。 #include stdio.h
int main()
{int zippo[4][2] { {2,4},{6,8},{1,3},{5,7} };printf( zippo %p, zippo 1 %p\n, zippo, zippo 1);printf(zippo[0] %p, zippo[0] 1 %p\n, zippo[0], zippo[0] 1);printf( *zippo %p, *zippo 1 %p\n, *zippo, *zippo 1);printf(zippo[0][0] %d\n, zippo[0][0]);printf( *zippo[0] %d\n, *zippo[0]);printf( **zippo %d\n, **zippo);printf(zippo[2][1] %d\n, zippo[2][1]);printf(*(*(zippo2) 1) %d\n, *(*(zippo 2) 1));return 0;
}
运行结果 zippo 二维数组首元素的地址(每个元素都是内含两个 int 类型元素的一维数组)
zippo2 二维数组的第 3个元素 (即一维数组)的地址
*(zippo2) 二维数组的第 3个元素(即一维数组)的首元素(一个 int 类型的值)地址
*(zippo2) 1 二维数组的第 3个元素(即一维数组)的第 2个元素(也是一个 int 类型的值)地址
*(*(zippo2) 1) 二维数组的第 3个一维数组元素的第 2个int 类型元素的值即数组的第3行第2 列的值 (zippo[2][1])
4、指针数组和数组指针
指针数组的本质其实是数组它里面存放的是指针数组中每个元素的类型是指针类型int*或char*。
指针数组的创建方式
int * arr[10] {0};
数组指针的本质其实是指针变量存放的是数组的地址能够指向数组的指针变量。
数组指针的创建方式
int (*pt)[10]; 数组指针的初始化
int arr[10] {0};
int (*pt)[10] arr;
字符指针变量
char* p hello;
这里本质上是把字符串“hello”首字符h的地址存放在p中。
5、函数指针变量
我们先来看一段代码
#include stdio.h
void test()
{printf(hehe\n);
}
int main()
{printf(test: %p\n, test);printf(test: %p\n, test);return 0;
}
运行结果 这说明函数是有地址的和数组一样函数名就是函数的地址。当然也可以通过函数名的方式后的函数的地址。
如果我们要将函数的地址存放起来就得创建函数指针变量。
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;//x和y写上或者省略都是可以的 函数指针变量的使用通过函数指针调用指针指向的函数。
#include stdio.h
int Add(int x, int y)
{return x y;
}
int main()
{int(*pf3)(int, int) Add;printf(%d\n, (*pf3)(2, 3));printf(%d\n, pf3(3, 5));return 0;
}
结果是 5 8