C语言精华题目锦集1

第一题

test.c文件中包括如下语句,文件中定义的四个变量中,是指针类型的是()【多选】

cpp 复制代码
#define INT_PTR int*
typedef int* intptr; 
INT_PRT a,b; 
int_ptr c,d;

A:aB:b ** C:c** ** D:d**


#define是宏定义,此时在程序中INT_PTR都会被替换为int*,变量a,b的定义如下:

int * a,b;

可以发现a确实为整型指针类型,而b则为整型类型。
而typedef是给该类型定义一个别名,使用该别名创建出的变量都是这个类型的。

第二题

对于以下说法,正确的是()
 A:对于struct X {short s;int i; charc},sizeof(X)sizeof(s)+sizeof(i)+sizeof(c )
 B:对于某个double变量a,可以使用a==0.0来判断其是否为0。
 C:初始化方式char a[14]="helloworld";和char a[14];a="hello world";的效果相同。
D:以上说法都不对


解析:

A:结构体大小的计算要考虑内存对齐问题。

B:这道题如果在VS上实验一下的话,会觉得B选项就是正确的,然而不然,因为该数据是double类型的数据,浮点数存在误差,不能直接判断两个数是否相等,通常是采用比较两数之差是否小于一个很小的数字,(具体可以自己设定一个这样的数,作为误差)来确定是否相等

例如:

运行结果是不是超脱预料之外?
调试观察sub1和sub2的数值。

可以发现误差是存在的,所以不能直接用一个浮点数是否等于0.0来判断该数是否为0。
C:a为数组首元素地址,是一个常量不可以改变。

第三题

请问下列表达式,哪些会被编译器禁止()【多选】

c 复制代码
int a=248,b=4;
int const*c=21;
const int*d=&a;
int *const e=&b;
int const* const f=&a;

** A:*c = 32;**
** B:*d = 43;**
** C:e = &a;**
** D:f = 0x321f;**


解析:

这道题是有关const修饰指针变量的题目,要记住只有两种情况,const在*前边的位置和const在*后边。如果const在*前边,就修饰的是指针变量指向的结果。

例如

int a=1;

const int *pa=&a;

int const *pa=&a;

只要const在pa的左边,那么const修饰的就是*pa,就不可以利用解引用得到a来修改a的值,此时a的值被固定了。
还有一种情况是const在*的右边

int a=0;

int b=0;

int * const pa=&a;
这种情况下const修饰的是a这个变量的地址,即pa的指向不能发生变化。此时如果要更改pa的指向如pa=&b,这样的操作是不被允许的。
如果觉得不好记忆的话,可以参考趣味讲解const修饰指针变量。

第四题

对于下边代码段,描述正确的是()

c 复制代码
t=0;
while(printf("*"))
{
	t++;
	if(t<3)
		break;
}

A:其中循环控制表达式与0等价。
B:其中循环控制表达式与'0'等价。
 C:其中循环控制表达式是不合法的。
 D:以上说法都不对。


解析:

这道题目选B,因为printf函数返回打印的字符·个数,所以判断条件恒为1,字符零不是零。

所以在这里B选项就是正确的。其他选项都是错误的。

编程题

1,至少是其他数字两倍的最大数

题目要求如下

第一种思路
遍历两边,第一遍找出最大值,第二遍判断是否找出的最大值是数组每个元素的二倍,如果满足条件就返回最大数字的下标,如果不满足,那就返回-1。
代码如下:

c 复制代码
int dominantIndex(int* nums, int numsSize){

   int i=0;
   int max=0;
 for(i=0;i<numsSize;i++)
   {
      if (nums[i] > max)
       {
           max = nums[i];
       }
   }
   int num=0;
   int flag=0;
   for(i=0;i<numsSize;i++)
   {
       if(nums[i]==max)
       {
           num=i;
       }
       else
       {
           if(nums[i]*2>max)
           {
               flag=1;
           }
       }
   }
   if(flag==0)
   {
       return num;
   }
   else
   {
       return -1;
  }
   return 0;
}

代码表达很清晰。

还有一种方法,在找到最大值时,也要保存倒数第二大的值。

代码如下:

c 复制代码
int dominantIndex(int* nums, int numsSize){
  int i=0;
  int max=nums[0];
   int max1=0;
   int flag=0;
   for(i=0;i<numsSize;i++)
   {
       if(nums[i]>max)
       {
           flag=i;
           max1=max;
           max=nums[i];            
       }
       if (max1 < nums[i]&&max!=nums[i])
       {
           max1 = nums[i];
       }
   }
   if(max>=2*max1)
   {
       return flag;
   }
   else
   {
       return -1;
   }
  return 0;
}

找到最大值的同时,保存第二大值,因为后边可能会出现比已经保存的第二大的值还要大的值,所以要继续向后遍历找到真正第二大的值,。最后进行判断即可。

第二题

自除数

只需要创建一个数组,得到right和left之间的所有满足条件的数即可,每一个数求出他的个位数,十位数,等等。


数据范围最大也只有10000。
像这种需要用的数字的每一位的数据进行判断的题目,最好还是创建一个大小为6的数组,装输入的数据的每个位的数字,方便最后进行判断。在解题的过程中要注意返回的数组必须是malloc申请的,不然就会有很多的报错。
代码如下(注释十分清晰)

c 复制代码
int* selfDividingNumbers(int left,int right,int *returnsize) 
{
    int*ccc=(int*)malloc(sizeof(int)*(right-left+1));
    int kkk[6];
    int l = 0;
    for (int i = left; i <= right; i++)
    {       
        int j = 0;
        int a = 1;
        int num = i;
        while (i > 0)//获取每位数字
        {
            kkk[j++] = i % 10;
            i = i / 10;
        }
        i = num;
        for (int k = 0; k < j; k++)
        {
            if (kkk[k] != 0)//如果数字中包含零,就不满足
            {
                if (i % kkk[k] != 0)
                {
                    a = 0;
                }
                else
                {
                    a = 1;
                }
            }
            else
            {
                a=0;
            }
        }
        if (a != 0)//如果该数字通过前边的测试
        {
            ccc[l++] = i;//将该数字存放在预留数组中。
        }
    }
    *returnsize = l;
    return ccc;
}

第三题

喝汽水问题
小明喝汽水,一瓶汽水1元,2个空瓶可以换一瓶汽水,小明现在有n元,求小明可以喝到多少瓶汽水?
思路一
将上述问题以代码形式解决,如果有n元,那么刚开始就有n个空瓶,假设全部喝完,然后拿着所有空瓶过去换汽水,就能换到n/2瓶汽水,喝完后于是又获得了n/2的瓶子,然后再去换,直到瓶子数目为0或者为1不足以再换汽水为止。
代码实现如下

c 复制代码
int main()
{
	int money = 0;//钱数
	int total = 0;//总共喝的汽水的数量
	int empty = 0;//空瓶的数量
	scanf("%d", &money);
	total = money;
	empty = money;
	while(empty>1)//只要空瓶数大于2,就能继续换
	{
		total += empty/2;
		empty = empty/2+empty%2;
	}
    printf("total = %d\n", total);//最终结果total
	return 0;
}

思路二

利用数学思维求解,我们可以利用上述代码多运行几次观察规律,会发现随着money的增长,能喝到的汽水的数量是一个等差数列。

1元--->1瓶汽水

2元--->3瓶汽水

3元--->5瓶汽水

。。。。

所以只要Money的数量不为0,只需要返回money*2-1即可。

代码如下

c 复制代码
int main()
{
	int money = 0;
	int total = 0;
	int empty = 0;
	scanf("%d", &money);	
	//方法2
	if(money <= 0)
	{
		total = 0;
	}
	else
	{
		total = money*2-1;
	}
	printf("total = %d\n", total);
	return 0;
}
相关推荐
Qter_Sean28 分钟前
自己动手写Qt Creator插件
开发语言·qt
何曾参静谧32 分钟前
「QT」文件类 之 QIODevice 输入输出设备类
开发语言·qt
爱吃生蚝的于勒2 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
小白学大数据4 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
冰芒猓4 小时前
SpringMVC数据校验、数据格式化处理、国际化设置
开发语言·maven
失落的香蕉4 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
红中马喽5 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
杜杜的man5 小时前
【go从零单排】Closing Channels通道关闭、Range over Channels
开发语言·后端·golang
java小吕布6 小时前
Java中Properties的使用详解
java·开发语言·后端
versatile_zpc6 小时前
C++初阶:类和对象(上)
开发语言·c++