余姚网站如何进行优化,qq排名优化网站,wordpress自建模板,深圳做网站500元指针---进阶篇#xff08;三#xff09; 一、前言二、一维数组例题透析#xff1a;三、指针笔试题1.例一#xff1a;2.例二#xff1a;3.例三#xff1a;4.例四#xff1a;5.例五#xff1a;6.例六#xff1a; 一、前言
那么好了好了#xff0c;宝子们#xff0c;从… 指针---进阶篇三 一、前言二、一维数组例题透析三、指针笔试题1.例一2.例二3.例三4.例四5.例五6.例六 一、前言
那么好了好了宝子们从今天开始开始总结暑假博客从指针开始后续来吧开始整活⛳️
二、一维数组例题透析
关于数组名的理解: arr,首先数组名是数组首元素的地址 毋庸置疑 arr,取地址符号加上数组名取出的是整个数组的地址
但是有2个例外: 1.sizeof后面括号内只有数组名的话计算的是整个数组的大小单位是字节。 2.加上数组名取出的是整个数组的地址
还有一点特别需要注意: 只要是指针也就是地址它的大小必然是4或8个字节4/8个字节的原因是在不同的环境下x86和x64。 1.int a[ ] { 1,2,3,4 };
#include stdio.h
int main()
{int a[] { 1,2,3,4 };printf(%d\n, sizeof(a));//计算的是整个数组的大小:4*416printf(%d\n, sizeof(a0));//sizeof(a0)得到的是数组首元素的地址4/8printf(%d\n, sizeof(*a));//a是数组首元素的地址*解引用后便是数组首元素1大小为4printf(%d\n, sizeof(a1));// Sizeof(a)是数组首元素地址,加1也就是数组第2个元素的地址只要是地址它的大小就是4/8个字节printf(%d\n, sizeof(a[1]));//数组的下标访问,不必多说直接就是:4printf(%d\n, sizeof(a));//这里不要被表面现象所迷惑了a取出的是整个数组的地址它本质上还是个地址所以说只要是地址它的字节大小就是:4/8printf(%d\n, sizeof(*a));//*和可以说是抵消了所以说本质上还是sizeof(a)一样的。计算的是整个数组的大小4*416printf(%d\n, sizeof(a1));//a取的是整个数组的地址加1也就是跳过了整个数组本质上他还是个地址所以说还是4/8个字节printf(%d\n, sizeof(a[0]));//他取出的是数组首元素的地址4/8个字节printf(%d\n, sizeof(a[0]1));//取出的是数组首元素的地址然后加1也就是取出的是数组中第2个元素的地址4/8个字节return 0;
}2.char arr[ ] { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’};
int main()
{char arr[] { a,b,c,d,e,f};printf(%d\n, sizeof(arr));//因为sizeof内部的括号只有arrarr代表整个数组的大小:1*6printf(%d\n, sizeof(arr0));//4/8printf(%d\n, sizeof(*arr));//这里的arr是数组首元素地址*后就是数组首元素大小为1个字节printf(%d\n, sizeof(arr[1]));//1printf(%d\n, sizeof(arr));//取出的是整个数组的地址地址的大小只有4/8printf(%d\n, sizeof(arr1));//4/8printf(%d\n, sizeof(arr[0]1));//4/8//声明strlen接收的参数类型是(指针)const char * str//strlen函数只有遇到‘\0’为结束标志printf(%d\n, strlen(arr));//随机值因为上面这个数组里面没有\0所以strlen要不断的往下遍历直到遇到\0为止。printf(%d\n, strlen(arr 0));//随机值printf(%d\n, strlen(*arr)); // errorarr是数组首元素的地址 * arr就是数组首元素就是a - 97//strlen函数参数的部分需要传一个地址当我们传递的是a时a的ASCII码值是97那就是将97作为地址传参//strLen就会从97这个地址开始统计字符串长度这就非法访问内存了printf(%d\n, strlen(arr[1]));//errorprintf(%d\n, strlen(arr));//随机值printf(%d\n, strlen(arr1));//随机值printf(%d\n, strlen(arr[0]1));//从第二个元素的地址开始访问还是随机值3.char arr[ ] “abcdef”;
char arr[] abcdef;printf(%d\n, sizeof(arr));//因为还有\0所以1*77printf(%d\n, sizeof(arr 0));//首元素的地址4/8printf(%d\n, sizeof(*arr));//对数组首元素地址*也就是第1个元素a:1printf(%d\n, sizeof(arr[1]));//1printf(%d\n, sizeof(arr));//整个数组的地址:4/8printf(%d\n, sizeof(arr 1));//4/8printf(%d\n, sizeof(arr[0] 1));//4/8printf(%d\n, strlen(arr));//6printf(%d\n, strlen(arr 0));//6printf(%d\n, strlen(*arr));//errorprintf(%d\n, strlen(arr[1]));//errorprintf(%d\n, strlen(arr));//整个数组的地址6printf(%d\n, strlen(arr 1));//取出整个数组的地址加1相当于指针这个数组指向最后一位的后面随机值printf(%d\n, strlen(arr[0] 1));//从b开始5个4.char* p “abcdef”;
char* p abcdef;printf(%d\n, sizeof(p));//4/8 :p是一个指针变量printf(%d\n, sizeof(p1));//4/8 :p1是b的地址是地址大小就是4/8个字节 printf(%d\n, sizeof(*p));//1 :就是aprintf(%d\n, sizeof(p[0]));//1 :就是aprintf(%d\n, sizeof(p));//4/8 :取出的是整个字符串的地址: char**printf(%d\n, sizeof(p 1));//4/8 :char**printf(%d\n, sizeof(p[0] 1));//4/8 :p[0] 1得到是b的地址printf(%d\n, strlen(p));//6printf(%d\n, strlen(p 1));// 5 printf(%d\n, strlen(*p));//errorprintf(%d\n, strlen(p[0]));//errorprintf(%d\n, strlen(p));//随机值printf(%d\n, strlen(p 1));//随机值printf(%d\n, strlen(p[0] 1));//55.二维数组int a[3][4] { 0 }; //二维数组int a[3][4] { 0 };printf(%d\n, sizeof(a));// a是数组名计算的是整个数组的大小3*4*448printf(%d\n, sizeof(a[0][0]));//第1行第1个元素的大小4printf(%d\n, sizeof(a[0]));//这里我们把a[0]看作一个一维数组的数组名:4*416printf(%d\n, sizeof(a[0]1));//a[0]作为第一行的数组名没有单独放在sizeo内部没有//a[0]表示数组首元素的地址也就是a[0][0]的地址 所以a[0]1是第一行第二个元素的地址是地址就是4/8个字节printf(%d\n, sizeof(*a[0]1));//4 //计算的是就是第一行第2个元素的大小printf(%d\n, sizeof(a1));// a不是单独放在size of内部就代表数组首元素地址也就是第1行数组的地址,加1也就是第2行数组的地址:4/8printf(%d\n, sizeof(*(a1)));//对第2行数组地址* 就是4*416printf(%d\n, sizeof(a[0] 1));//因为a[0]是第一行数组的数组名对第1行数组数组名取地址之后再加1也就是第2行数组的地址4/8printf(%d\n, sizeof(*(a[0] 1)));//对第2行数组地址整个*4*416printf(%d\n, sizeof(*a));//如果a不是单独放在size of内部那么a就代表数组首元素地址也就是数组第1行的地址 *后4*416printf(%d\n, sizeof(a[3]));//a[3]代表第三行数组数组名4*416对二维数组的深度理解
三、指针笔试题
1.例一 int main()
{int a[5] { 1,2,3,4,5 };int* ptr (int*)(a 1);//取地址加数组名 a取出的是整个数组的地址再1指向5的后面printf(%d %d, *(a 1), *(ptr - 1));//a1:就是数字数元素地址加1然后*后就是2;//刚开始ptr指的是5的后面,再减1就是指向了5return 0;
}2.例二
这道题主要考察的是指针类型:决定了指针1到底加几
//由于还没学习结构体这里告知结构体的大小是20个字节
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}* p (struct Test*)0x100000;//假设p 的值为0x100000。 如下表表达式的值分别为多少
//已知结构体Test类型的变量大小是20个字节
int main()
{printf(%p\n, p 0x1);//0x1000001:因为p是一个结构体指针结构体指针1跳的是整个结构体也就是加了20个字节//0x10000020错因为0x100000是16进制的0x100014printf(%p\n, (unsigned long)p 0x1);//在这里我们把结构体指针强制类型转化为无符号的数字10x100001printf(%p\n, (unsigned int*)p 0x1);//这里我们把结构体指针p强制类型转化为int*1就跳过4个字节0x100004return 0;
}注意前提环境为X86
3.例三
int main()
{int a[4] { 1, 2, 3, 4 };int* ptr1 (int*)(a 1);int* ptr2 (int*)((int)a 1);printf(%x,%x, ptr1[-1], *ptr2);//ptr1:4;// a是数组首元素地址,把a数组首元素地址强制转换为int整型,强制转化为int整型之后再1就是单纯的加数字1了,之后再将这个数字强制转化为int*。//打印的是地址return 0;
}4.例四
考察逗号表达式
int main()
{int a[3][2] { (0, 1), (2, 3), (4, 5) };//不要被表面现象所迷惑了如果012345要存到二维数字中它每个数组都要用大括号括起来//而它是用小括号所以说它是一个逗号表达式所以说实际上存进去的只有1 3 5这三个数字后面其他的都是0int* p;p a[0];//a[0]之前不是讲过了吗是第1行数组的数组名:也就是第1行数组首元素的地址。printf(%d, p[0]);//1return 0;
}5.例五
int main()
{int aa[2][5] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int* ptr1 (int*)(aa 1);int* ptr2 (int*)(*(aa 1));printf(%d,%d, *(ptr1 - 1), *(ptr2 - 1));//1.ptr1:取地址数组名aa是取出了整个数组的地址再加一就是跳过整个二维数组。-1指向了10//2.ptr2:aa是数组首元素地址在二维数组中我们把每一行看作一个元素1的话就是跳过了第1行指向了第2行首元素的地址-1指向了5return 0;
}6.例六
需要画图才能一目了然
int main()
{char* c[] { ENTER,NEW,POINT,FIRST };char** cp[] { c 3,c 2,c 1,c };char*** cpp cp;printf(%s\n, **cpp);printf(%s\n, *-- * cpp 3);printf(%s\n, *cpp[-2] 3);printf(%s\n, cpp[-1][-1] 1);return 0;
}好了今天的分享就到这里了
如果对你有帮助记得点赞关注哦 我的主页还有其他文章欢迎学习指点。关注我让我们一起学习一起成长吧