前言:
欢迎打开这篇博客,从今天开始,每天和大家分享一个C语言小细节,不久之后还会追加C++
一些常常被忽视的小细节和思想统一的编程题目是这个专栏的核心哦
虽然简单但千万别在细节处失分!!!!
每日花一两分钟浏览一下加深一个知识点不香吗
感兴趣的赶紧收藏关注起来吧,不要迷路~
我们今天主要练习一些数组,字符串的小题和编程题,对这部分还不是很了解的小伙伴可以去看数组指针,指针数组一锅粥,二级指针深度理解(附编程题练习)
当然如果很基础的数组知识也有所遗忘的话可以去
一维数组和二维数组的命名以及存储空间
1.
这段代码的输出是什么?
首先s是指针数组,数组的每一个元素是字符串首字母的地址,函数传参之后p就是s的临时拷贝,本质还是一样的,p[1]就代表s中第一个字符串(“ABCD”)的首字母地址,p[i],i每++,就是跳过一个首字母地址,也就是跳过一个字符串,所以p[0],p[1],p[2],p[3]就是字符‘A’‘E’‘I’‘M’的地址
打印以%s的格式,看到s[i](p是s的临时拷贝,没有本质区别)中存放的地址,输出s[i]存储的指针指向的字符串。
所以最后结果就是 字符‘A’‘E’‘I’‘M’ 为首的四个字符串
2.
A:拿到数组第一个元素的地址,a[0][0]代表一个元素,+5就是跳过五个元素,又a数组是3行4列(都是下标从0开始)所以指向a[1][1]的地址,解引用找到
B:a数组除了可以表示一个二维数组的名字还可以把a理解成里面存放四个行向量首元素的地址,也就是每一行第一个元素的地址,所以a后面什么都不加就表示第一行第一个元素的地址,+1跳到下一行(因为指针+-数字是看指针的类型是什么,+-之后就跳过多少个同类型的元素)
*(a+1)解引用来到第二行现在的元素类型变成原数组元素的地址,+1就是找到第二行第二列的元素地址然后解引用就可以
C,D:区别就在要不要&
如果不加&就a[1]表示第二行的首元素地址,直接+1又跳过一个元素,完美找到第二行第二个元素
但是加上&, a[1]就表示a[1][0]的地址,又加上&想表示什么?地址的地址,那么+1就跳过一行,走远了
所以C选项错误
3.
A选项,f(a)传参时,a会退化成指向其首元素的地址,类型是 int*,不符。
B选项,b是二维数组,传参时会退化成指向其首元素的指针,也就是b[0]的地址,b[0]的类型是int [4],故&b[0]类型是int(*)[4],不符。
D选项,&a是数组a的地址,其类型是int(*)[4],不符。
C选项,q是一个指针数组,在初始化时用b[0]、b[1]、b[2], 此时b[0]、b[1]、b[2]会退化成指向各首元素的指针(int* 类型,因此类型符合,可以用它们初始化)。q传参时,退化成指向其首元素的指针,即 int**,符合
4.NC31 第一个只出现一次的字符 牛客传送
不知道大家记不记得之前在刷剑指offer的时候,就有相似的方法是对于字符串吗,用一个大小为128的数组记录每一个字符出现的次数,出现一次就在对应码值下标的位置++,本题也是类似
int FirstNotRepeatingChar(char* str ) {
// write code here
//int a[128]={0};
int a[128]={0};
int t=0;
for(int i=0;*(str+i)!='\0';i++)
{
t=*(str+i);
a[t]++;
}
for(int i=0;*(str+i)!='\0';i++)
{
t=*(str+i);
if(a[t]==1)
return i;
}
return -1;
}
还有一个极其相似的题目
判定字符是否唯一力扣传送
其实就是最后的判断条件不太一样,简直是原题
bool isUnique(char* astr){
int a[128] = { 0 };
int t = 0;
for (int i = 0; *(astr + i) != '\0'; i++)
{
t = *(astr + i);
a[t]++;
}
for (int i = 0; *(astr + i) != '\0'; i++)
{
t = *(astr + i);
if (a[t] != 1)
return false;
}
return true;
}
今天的小细节分享就到这里了,希望你真的对二维数组有更多的了解