首页 > 试题广场 >

以下代码输出什么() char *a[] = {"BEIJI

[单选题]
下列代码输出是()
char *a[] = {"BEIJING", "SHENZHEN", "SHANGHAI", "GUANGZHOU"};
char **pa[] = {a+3, a+2, a+1, a};
char ***ppa = pa;
int main(void) {
    printf("%s, ", **++ppa);
    printf("%s, ", *--*++ppa+3);
    printf("%s, ", *ppa[-2]+3);
    printf("%s", ppa[-1][-1]+1);
}

  • BEIJING, SHENZHEN,  SHANGHAI,GUANGZHOU
  • SHANGHAI, JING, NGZHOU, HENZHEN
  • SHANGHAI,BEIJING, GUANGZHOU, SHENZHEN
  • SHANGHAI,EIJING,ZHOU,ZHEN

图片说明

/*
  对于指针ppa
        指针类型:char ***
        指针指向:pa[0]
        指针指向类型:char **
  //指针的指向决定其偏移起始位置,指针指向的类型决定其每次移动偏移量大小 
*/
printf("%s, ", **++ppa);
/*
    运算符优先级:++ 与 * 运算符同优先级,结合性都是自右向左
    ++ppa
        ppa自增,指向改变,向后移动一位,偏移量为char **,指向pa[1]
    *++ppa
        取出内容,pa[1],pa[1]又指向a[2]
    **++ppa
        取出内容,a[2],a[2]又指向字符串"SHANGHAI",printf输出 SHANGHAI
*/
printf("%s, ", *--*++ppa+3);
/*
    运算符优先级:++/-- 优先级大于 + ,且 + 的结合性是从左往右
    ++ppa
        上一次操作已改变ppa的指向为pa[1],再次移动,指向pa[2]
    *++ppa
        取出内容,pa[2],pa[2]又指向a[1]
    --*++ppa
        //此时,【*++ppa】是一个char **指针,指向a[1],
//则其偏移的起始位置为a[1],偏移量为char *
        --使其自减,指针向前移动,从a[1]向前移动一个char*的大小,指向a[0]
    *--*++ppa
        取出内容,a[0],a[0]又指向字符串"BEIJING"
    *--*++ppa+3
        //此时【*--*++ppa】是一个char *指针,指向一个字符串,则其偏移的起始位置
//为字符串的首字符,偏移量为char
        +3使指针向后移动3次,每次移动一个char,移动完成后指向字符'J' ,printf
输出,从字符'J'的位置往后输出打印到STDOUT,输出 JING
*/
 printf("%s, ", *ppa[-2]+3);
/*
    []作用符:【例子】
    int arr[]{ 0,1,2,3 };
    int *p=arr;
    ++p;
    cout << p[1] << " " << *(p + 1) << endl;
    cout << p[-1] << " " << *(p - 1) << endl;
    //p[1]等价于*(p + 1)   p[-1]等价于*(p - 1)
    ppa[-2]
        等价于*(ppa-2)
            ppa-2
                //经过前两次操作,ppa指向pa[2],移动后指向pa[0],【但ppa
//本身的指向并没有改变,还是指向pa[2]】
            *(ppa-2)
                取出内容,pa[0],pa[0]又指向a[3]
    *ppa[-2]
        取出内容,a[3],a[3]又指向字符串"GUANGZHOU"
    *ppa[-2]+3
        +3使指针移动到字符'N',printf输出 NGZHOU 
*/
printf("%s", ppa[-1][-1]+1);
/*
    //类似与ppa[-2]等价于*(ppa-2),ppa[-1][-1]等价于*(*(ppa-1)-1)
    ppa[-1]
        等价于*(ppa-1)
            //经过前三步操作,ppa指向pa[2],移动后,指向pa[1],
//取出内容pa[1],pa[1]又指向a[2]
    ppa[-1][-1]
        等价于*(*(ppa-1)-1)
            *(ppa-1)-1
                将上一步操作中的*(ppa-1)看做一个整体,是一个char **指针,
指向类型为char * 的a[2]
                则指针 *(ppa-1) 偏移的起始位置为a[2],向前移动一次,
偏移量为char *,移动后指向a[1]
            *(*(ppa-1)-1)
                取出内容,a[1],a[1]又指向字符串"SHENZHEN"
    ppa[-1][-1]+1
        +1指针其移动到字符'H',printf输出 HENZHEN
*/
编辑于 2020-01-05 16:22:43 回复(18)
第5行:**++ppa:      ++ppa,指向pa[1],第一次解引用,指向a[2],再解引用,即是字符串shanghai,输出结果为shanghai
第6行:*--*++ppa+3;     当前ppa指向pa[1],++ppa,则ppa指向pa[2],解引用,指向a[1],--a,则当前指针为a[0],解引用,指向字符串beijing,再偏移3个位置,输出即为jing
第7行:*ppa[-2]+3:    () 当前ppa指向pa[2],ppa[-2]等价于*(pa-2),所以使得指针指向pa[0]并解引用,指向a[3],再解引用,指向字符串gaungzhou,偏移3个单位,输出结果则为ngzhou
第8行:ppa[-1][-1]+1:   当前ppa指向pa[2],类似第7行的,ppa[-1][-1]使得指向字符串shenzhen,再偏移一个单位,输出为henzhen

个人理解,也是很懵逼,描述有错请指正
编辑于 2019-09-08 19:14:40 回复(7)
顺丰使java程序猿学会了C++
发表于 2019-08-12 16:52:35 回复(3)
本题考查指针数组和多级指针的概念
(1)数组a是一个指针数组,里面每一个元素都是一个一级指针
(2)数组pa也是一个指针数组,里面每一个元素都是一个二级指针
(3)每次取一次*指针的级数会降一级。
本题的重点主要是弄清楚++/--和*是针对哪一个级别的指针的,而且要注意a[2]--后是a[1].
printf("%s, ", **++ppa);
//++ppa后ppa指向a+3,在*ppa指向a[3]即为Shanghai
printf("%s, ", *--*++ppa+3);
//++ppa后ppa指向a+2,再*ppa指向a[2],然后--*++ppa指向a[1],再计算*--*++ppa为beijing,再+3偏移变为Jing
printf("%s, ", *ppa[-2]+3);
//ppa当前所指向a+1,ppa[-2]即为当前ppa前第二个元素,即为a+3,然后再计算*ppa[-2]+3即为NGZhou
printf("%s", ppa[-1][-1]+1);
//ppa当前所指向a+1,ppa[-1]即为a+2,再计算ppa[-1][-1]为a[1],即shenzhen,然后计算+1为henzheng


编辑于 2019-08-21 17:52:15 回复(1)
ppa指向了pa,然后第一个printf之后经过了++操作,也就是pa+1,存放着a+2的地址,而a+2指向的是“shanghai”,然后取两次内容就打印出了“shanghai”,第二个printf,也是先++操作,也就是pa+2,存放着a+1的地址,而a+1又指向的是“shenzhen”,而取地址符优先于算数运算符,然后取内容再--操作也就得到了a这个原指针数组,再取一次内容就是指向beijing的地址再偏移三位打印出来就得到了“jing”,然后后面同理,从三级指针一步一步脱下外套,就能正确的得到答案😄,不过谁要是在工作中这样子写,估计会被喷🤣
发表于 2021-08-24 22:05:21 回复(0)
<p>有意思吗,有谁这么写代码的嘛🙄</p>
发表于 2020-08-23 17:11:21 回复(0)

char* a[]是定义一个字符串数组。

a是数组名,所以它是第一个字符串的指针,同理a+1是第二个。

所以,char **pa[] 的元素是字符串的指针,char*是字符串,再来一个*便是字符串指针。

pa是数组名,同理是第一个元素的指针,即字符串指针的指针

所以***ppa=pa

++ppa,是a+2的指针,*取一次,得”SHANGHAI”的指针,再*取一次,得”SHANGHAI”字符串。

++ppa为a+1的指针,*++ppa为a+1,- -*+ppa为a,*- -*+ppa为”BEIJING”字符串(也是首字符’B’的地址),*- -*+ppa+3即字符’J’的地址,打印得”JING”。

后面不写了。

发表于 2020-01-14 21:03:03 回复(0)
首先明确**pa[]是一个数组,存放的是指针的指针。 ppa和pa指向的内容相同,ppa指向a+2,第一个输出++ppa指向shanghai 第二个输出++ppa指向a+1,––*a+1取出a+1的值并自减1,因此指向a,再+3指向J,输出J后面的内容 第三个由于ppa指向a+1的位置,向前两个位置就是a+3(在pa数组中),再加3输出N以后内容 第四个同理,ppa[-1]指向a+2(pa数组中),a+2的前一个位置就是a+1(a数组中),因此再加1输出H以后内容 更多的 paa+1 pa数组中跳过一个指针的指针元素如a+3 *paa+1 取出一个指针的指针元素并加1 如(a+1)+1
发表于 2019-08-13 22:25:53 回复(1)
求解答  虽然蒙对了
发表于 2019-07-31 15:03:43 回复(0)
前置++和*同级运算符先计算,+优先级低最后计算 一级运算符:标识,常量,字符串文字量,优先级提升表达式最优先执行。 二级运算符:数组下标运算(expression)、函数调用(argument-expression-list)、成员访问(identifier、 -> identifier)、后缀自增(i++)、后缀自减(i–)、 复合初始化(initializer-list)。 三级运算符:前缀自增(++i)、前缀自减(–i)、单目转型表式式(取地址& ,提领 * , 正号+ ,负号-、 位反~ 逻辑否!)、求类型长度(sizeof unary-expression)。 四级运算符:强制表达式成为type-name指定的类型( type-name ) cast-expression。 五级运算符:“ * ” 乘法运算符。 六级运算符:“ + ”加法运算符。 七级运算符:<< 左移运算符;>> 右移运算符。 八级运算符:<、<=、>、>=关系运算符。 九级运算符:“ == ”等于运算符;“ != ”不等于运算符。 十级运算符:“ & ”按位与运算符。 十一级运算符:“ ∧ ”按位异或运算符。 十二级运算符:“ | ”按位或运算符。 十三级运算符:“&&”逻辑与运算符。 十四级运算符:“ || ”逻辑或运算符。 十五级运算符:? :条件运算符。
发表于 2022-06-23 14:22:08 回复(2)
只要知道第二个要么是j开头要么是N开头,就知道选B了
发表于 2023-07-15 00:21:04 回复(0)
真绝自已是个废物
发表于 2023-03-28 20:41:32 回复(0)
前面的运算导致ppa指向发生了变化。
发表于 2023-03-10 08:35:24 回复(0)
这个题稍微变换下就好理解了 、
    
    第一次指针变量赋值可以这样改 
    char **a= {"BEIJING","SHENZHEN","SHANGHAI","GUANGZHOU"};
    
    第二次赋值
    char ***pa=  {a+3,a+2,a+1,a};
    
    地址    地址    地址    地址    内容 
    ppa0--->pa0--->&(a+3)--->a+3==>"GUANGZHOU" 
    ppa1--->pa1--->&(a+2)--->a+2==>"SHANGHAI" 
    ppa2--->pa2--->&(a+1)--->a+1==>"SHENZHEN"
    ppa3--->pa3--->&(a+0)--->a+0==>"BEIJING"
    
    
    
    printf("%s, ", **++ppa);
    **++ppa   ppa+1 指向ppa1 然后取地址内容  a+2的地址  再取地址a+2的内容  "SHANGHAI" 

    printf("%s, ", *--*++ppa+3);
    *--*++ppa+3  ppa 先加1指向ppa2  取地址为a+1  指针的地址减1  a+0  然后取地址内容  BEIJING  输出 +3  内容  JING
    
    printf("%s, ", *ppa[-2]+3);
    *ppa[-2]+3   ppa[-2] 可以看做 *(ppa-2)  ppa 已经指到ppa2了  所以结果 *ppa0   
                就变成了  **ppa0+3   **ppa0 最后是a+0的内容 GUANGZHOU
                输出+3   内容为   NGZHOU
    
    printf("%s, ", ppa[-1][-1]+1);
    ppa[-1][-1] 一次变换  *(ppa-1)[-1]  再变换 *( *(ppa-1)-1)   ppa指向ppa2   减1 后指向ppa1  取地址后为a+2  
    地址再减1  a+1  最后取出a+1的内容   SHENZHEN  输出+1   HENZHEN
    
发表于 2022-10-13 12:32:54 回复(0)
这种代码有什么意义
发表于 2022-10-12 21:34:11 回复(0)
首先明确a是一个指针数组,存放了指向这四个字符串首元素地址的指针,pa存放了指向a中指针元素的指针,ppa得到pa首元素地址。
发表于 2022-08-25 11:07:44 回复(1)
重点是有没有注意到上次的++操作改变了原来的位置
发表于 2020-09-15 23:10:23 回复(0)
printf("%s, ", **++ppa);
//++ppa后ppa指向a+2,在*ppa指向a[2]即为SHANGHAI
printf("%s, ", *--*++ppa+3);
//++ppa后ppa指向a+1,再*ppa指向a[1],然后--*++ppa指向a[0],再计算*--*++ppa为BEIJING,再+3偏移变为JING
printf("%s, ", *ppa[-2]+3);
//ppa当前所指向a+1,ppa[-2]即为当前ppa前第二个元素,即为a+3,然后再计算*ppa[-2]为GUANGZHOU,*ppa[-2]+3即为NGZHOU
printf("%s", ppa[-1][-1]+1);
//ppa当前所指向a+1,ppa[-1]即为a+2,再计算ppa[-1][-1],为*(a+2-1)即a[1],即SHENZHEN,然后计算+1为HENZHENG


发表于 2019-09-28 12:50:44 回复(0)
D&J头像 D&J
在公司,你要是这么写代码,不仅过不了检视,还会被喷
发表于 2019-08-30 11:00:32 回复(0)
已屏蔽
发表于 2019-08-22 14:21:57 回复(0)