• 【C/C++笔试练习】——数组名和&数组名、switch循环语句、数据在计算机中的存储顺序、字符串中找出连续最长的数字串、数组中出现次数超过一半的数字


    C/C++笔试练习

    1.数组名和&数组名

    (1)数组名和&数组名的差异

      以下C语言指令:

    int a[5] = {1,3,5,7,9};
    int *p = (int* )(&a+1);
    printf(%d,%d”,*(a+1)*(p-1));
    
    • 1
    • 2
    • 3

      运行结果是什么?

      A 2,1    B 3,1
      C 3,9    D 运行时崩溃

      

      数组名和&数组名在C和C++编程语言中具有不同的含义。

      数组名:数组名是用于引用数组的标识符。它可以是任何有效的标识符,通常用于对数组进行索引和访问数组元素。假设有一个名为“arr”的数组,就可以使用“arr[0]”来访问第一个元素,以此类推。

      &数组名:在C和C++中,&运算符用于获取变量的地址。因此,&数组名是用来获取数组的地址。这通常用于传递数组到函数或从函数返回数组。当你使用&数组名时,你实际上得到的是一个指向数组的指针。

      因此,数组名和&数组名的主要区别在于:数组名代表的是数组中的元素,而&数组名代表的是整个数组的地址。

    在这里插入图片描述

      结合上面内容,所以这段C++的代码中,定义了一个包含5个整数的数组a,然后创建了一个指向整个数组类型的指针p,&a代表了取整个数组,(&a+1)代表指针需要跳过一个a的类型大小,此时的a是一整个数组,所以(&a+1)代表了向后偏移一个数值大小, 此时的p指向数组最尾段的下一个int类型的地址。

      然后打印* (a+1)和 * (p-1)),a是数组名,数组名不加修饰的,代表了数组首元素的大小,(a+1)表示地址向后偏移一个a类型大小的指针,此时的a为int,(a+1)就表示指向a数组的第二个元素,*(p-1)代表p向前移动一个数据类型大小,指向9,即可得到结果。

      
    在这里插入图片描述
       答案选:C

                 

    (2)理解数组名和指针偏移

      以下程序的输出结果是()

    #include 
    main() 
    {
    	char a[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 0}, *p;
    	int i;
    	i = 8;
    	p = a + i;
    	printf("%s\n", p - 3);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

      A 6      B 6789
      C ‘6’    D 789

      首先,数组a被初始化为字符数组,包含10个元素,值为’1’到’9’和’\0’。然后创建一个指针p=a,此时的a不加&修饰,就表示数组的首元素地址 ‘1’ 元素的地址。然后对a+8,表示指向首元素的地址向后偏移8个数据类型大小,此时p指向9。(0和’\0’是一样的)

      在printf语句中,先将p向前移动3个位置,即指向了字符’6’,然后再打印字符串。输出的是从’6’开始的4个字符,即’6789’。

    在这里插入图片描述

       答案选:B

                 

    (3)理解数组名代表的含义

       以下代码

    char *ptr;
    char myString[] = "abcdefg";
    ptr = myString;
    ptr += 5;
    cout<<ptr;
    
    • 1
    • 2
    • 3
    • 4
    • 5

       代码执行之后的结果是?
       A Compiler error       B fg
       C efg              D defg

      结合上面的内容,我们容易知道ptr是一个char类型的指针,此时的ptr指向myString数组的首元素地址,对ptr+=5,ptr指针向后偏移5个指向元素类型大小的距离。此时的ptr指向f,cout<

    在这里插入图片描述

       答案选:B

                 

    (4)理解数组名代表的含义

       下面代码会输出()

    int main()
    {
    	int a[4]={1,2,3,4};
    	int *ptr=(int*)(&a+1);
    	printf("%d",*(ptr-1));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

       A 4       B 1
       C 2       D 3

      结合上面的内容,我们容易知道ptr是一个(int*)(&a+1)的指针,对&a+1,表示指针向后面偏移一整个数组的大小,此时ptr指针指向4元素的后面一个元素。

      要注意(&a+1)赋值给ptr的时候强转成了(int*)的指针,要注意此时指向整个数组的指针成为了指向一个数组元素的指针。 打印时对ptr-1表示指针,向前偏移一个(int*)类型大小,此时ptr指向4。

    在这里插入图片描述
       答案选:A

                 

    2.switch循环语句

    (6)理解switch语句中的case特点

      以下程序的输出结果是()

    #include 
    int main()
    {
    	int x=3,y=3;
    	switch(x%2)
    	{
    		case 1:
    		switch (y)
    		{
    			case 0:
    				cout<<"first";
    			case 1:
    				cout<<"second";
    				break;
    			default:
    				cout<<"hello";
    		}
    		case 2:
    		cout<<"third";
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

      A second third      B hello
      C first second       D hellothird

       在这个程序中,当x%2的结果为1时,y的值为3,所以会先进入到(x%2)的case1中;然后y=3,case1和case2都不满足,直接default,打印hello,注意下面的语句没有break,所以程序会继续向下执行,进入到(x%2)中的case2,打印third。

       正常情况下,在C++中,每个case标签后都应该有一个break语句,来防止程序继续执行下一个case。如果没有break,程序将会继续执行下一个case的代码, 直到遇到break或者switch结束。

    在这里插入图片描述
       答案选:D

                 

    3.数据在计算机中的存储顺序

    (7)小端在计算机中的存储方式

      假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?

    #include 
    int main()
    {
    	long long a = 1, b = 2, c = 3;
    	printf("%d %d %d\n", a, b, c);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

      A 1,2,3      B 1,0,2
      C 1,3,2      D 3,2,1

      在计算机中数据的存储分为大端和小端存储,什么是大端小端:

      大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;

      小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

    在这里插入图片描述

       答案选:B

       设计一个函数来判断当前机器的字节序:

    void check_sys()
    {
    	int i = 1;
    	if (*(char*)&i == 0)
    	{
    		cout << "大端";
    	}
    	else
    	{
    		cout << "小端";
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

                 

    4.编程题

    (8)字符串中找出连续最长的数字串

    字符串中找出连续最长的数字串

      解题思路:

      遍历字符串,使用cur去记录连续的数字串,如果遇到不是数字字符,则表示一个连续的数字串结束了,则将数字串跟之前的数字串比较,如果更长,则更新更长的数字串更新到ret。

    #include 
    using namespace std;
    
    int main() {
        string str,ret,cur;
        cin>>str;
        for(int i=0;i<=str.size();i++)//遍历整个字符串
        {
            //如果是数字就加入到临时数字串cur中
            if(str[i]>='0'&&str[i]<='9')
            {
                cur+=str[i];
            }
            else//如果遇到了字符就和ret比较,保存较大的数字串
            {
                if(cur.size()>ret.size())
                {
                    ret=cur;
                    cur.clear();
                }
                else//如果cur比ret长,替换ret,否则重置cur
                {
                    cur.clear();
                }
            }
        }
        cout<<ret;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

                 

    (9)数组中出现次数超过一半的数字

      解题思路1:

      众数:就是出现次数超过数组长度一半的那个数字,如果两个数不相等,就消去这两个数,最坏情况下,每次消去一个众数和一个非众数,那么如果存在众数,最后留下的数肯定是众数。

    class Solution {
      public:
        int MoreThanHalfNum_Solution(vector<int> numbers) {
            if (numbers.empty()) return 0;
    // 遍历每个元素,并记录次数;若与前一个元素相同,则次数加1,否则次数减1
            int result = numbers[0];
            int times = 1; // 次数
            for (int i = 1; i < numbers.size(); ++i) {
                if (times != 0) {
                    if (numbers[i] == result) {
                        ++times;
                    } else {
                        --times;
                    }
                } else {
                    result = numbers[i];
                    times = 1;
                }
            }
    // 判断result是否符合条件,即出现次数大于数组长度的一半times = 0;
            for (int i = 0; i < numbers.size(); ++i) {
                if (numbers[i] == result) ++times;
            }
            return (times > numbers.size() / 2) ? result : 0;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

      

      解题思路2:

       数组排序后,如果符合条件的数存在,则一定是数组中间那个数。但是时间复杂度稍高。

    class Solution {
    public:
        int MoreThanHalfNum_Solution(vector<int>& numbers) {
            sort(numbers.begin(),numbers.end());
            return numbers[numbers.size()/2];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    keepalived的vip实现nginx节点的主备
    strlen函数详解及模拟实现
    【限定词习题】all
    安培龙IPO过会:年营收5亿 同创伟业与中移创新是股东
    NodeMCU ESP8266开发流程详解(图文并茂)
    IB中文语言与文学:答题习惯和思路
    计算机网络复习总结3
    Salesforce LWC学习(四十六) record-picker组件浅谈
    搞透 IOC,Spring IOC 看这篇就够了!
    ant target的depends属性
  • 原文地址:https://blog.csdn.net/Crocodile1006/article/details/133410595