12个关于C语言的有趣问答

本文汇总了12个关于C语言的问答,对于加深对C语言程序设计的难点理解很有帮助,读者可参考一下:

1、gets() 方法

问:以下代码有个被隐藏住的问题,你能找到它吗?

答:这个不显眼的问题就是使用了 gets() 方法。此方法接受一个string类型参数,但是却没有检测此数值是否 有足够的空间来拷贝数据。所以这里我们一般用 fgets() 方法将来的更好。

#include<stdio.h>

int main(void)
{
  char buff[10];
  memset(buff,0,sizeof(buff));

  gets(buff);

  printf("\n The buffer entered is [%s]\n",buff);

  return 0;
}

2、strcpy() 方法

问:密码防护是很基本的功能,看看能否搞定下面这段代码?

#include<stdio.h>

int main(int argc, char *argv[])
{
  int flag = 0;
  char passwd[10];

  memset(passwd,0,sizeof(passwd));

  strcpy(passwd, argv[1]);

  if(0 == strcmp("LinuxGeek", passwd))
  {
    flag = 1;
  }

  if(flag)
  {
    printf("\n Password cracked \n");
  }
  else
  {
    printf("\n Incorrect passwd \n");

  }
  return 0;
}

3、main() 方法的返回类型

问:请问下面这段代码能否通过编译?如果能的话,那么这段代码中隐含什么问题吗?

#include<stdio.h>

void main(void)
{
  char *ptr = (char*)malloc(10);

  if(NULL == ptr)
  {
    printf("\n Malloc failed \n");
    return;
  }
  else
  {
    // Do some processing

    free(ptr);
  }

  return;
}

答:答案是代码能通过编译,但是会留下针对main()方法的返回类型的警告。main()方法的真正返回类型应该为'int'而非'void'。这是因为'int'返回类型能够让程序返回状态值。尤其是当这段程序作为其他应用的附属程序时这个状态值将更加重要。

4、内存泄露

问:请问以下代码有内存泄露吗?

#include<stdio.h>

void main(void)
{
  char *ptr = (char*)malloc(10);

  if(NULL == ptr)
  {
    printf("\n Malloc failed \n");
    return;
  }
  else
  {
    // Do some processing
  }

  return;
}

答:好,虽然上面的代码没有对指针 ptr 进行内存释放,但实际上即使是程序结束也不会造成内存泄露,因为当程序结束时所有一开始被占据的内存就全部清空了。但如果上面这段代码是在 while 循环里面那将会造成严重的问题

补充: 如果你需要了解更多关于内存泄露的问题,你可以参考这篇文章http://www.jb51.net/article/41216.htm

5、free() 方法

问:以下代码当用户输入'freeze'时会奔溃,而如果输入'zebra'则运行正常,这是为什么?

#include<stdio.h>

int main(int argc, char *argv[])
{
  char *ptr = (char*)malloc(10);

  if(NULL == ptr)
  {
    printf("\n Malloc failed \n");
    return -1;
  }
  else if(argc == 1)
  {
    printf("\n Usage \n");
  }
  else
  {
    memset(ptr, 0, 10);

    strncpy(ptr, argv[1], 9);

    while(*ptr != 'z')
    {
      if(*ptr == '')
        break;
      else
        ptr++;
    }

    if(*ptr == 'z')
    {
      printf("\n String contains 'z'\n");
      // Do some more processing
    }

    free(ptr);
  }

  return 0;
}

答:问题的根源是因为代码在while循环中改变了 ptr 指针的地址。当输入为'zebra'时,while循环甚至在执行 第一遍前就结束了,所以free()释放的内存地址就是一开始malloc()分配的地址。但是当输入'freeze'时, ptr记录的地址在while循环中被更改,因为将会是错误的地址传递到free()方法中引起崩溃。

6、atexit with _exit

问:在以下代码,atexit()方法并没有被调用,你知道为什么吗?

#include<stdio.h>

void func(void)
{
  printf("\n Cleanup function called \n");
  return;
}

int main(void)
{
  int i = 0;

  atexit(func);

  for(;i<0xffffff;i++);

  _exit(0);
}

答:这是因为使用了 _exit() 方法。此方法并没有调用清除数据相关的方法,比如 atexit()等。

7、void* 与 C 结构体

问:能否设计一个方法接受任意类型的参数然后返回整数?同时是否有办法传递多个这样的参数?

A:一个能接受任意类型参数的方法像下面这个样子:

int func(void *ptr)

如果需要传递多个参数,那么我们可以传递一个包含这些参数的结构体

8、* 与 ++ 操作符

问:以下代码将输出什么?为什么?

#include<stdio.h>

int main(void)
{
  char *ptr = "Linux";
  printf("\n [%c] \n",*ptr++);
  printf("\n [%c] \n",*ptr);

  return 0;
}

答:以上的输出将是:

因为++与 * 的优先级一样,所以 *ptr++ 将会从右向左操作。按照这个逻辑,ptr++ 会先执行然后执行*ptr。所以第一个结果是'L'。也因为 ++ 被执行了,所以下一个printf() 结果是'i'。

9、Making changes in Code segment

问:以下代码运行时一定会崩溃,你能说出原因吗?

#include<stdio.h>

int main(void)
{
  char *ptr = "Linux";
  *ptr = 'T';

  printf("\n [%s] \n", ptr);

  return 0;
}

答:这是因为,通过 *ptr = ‘T',此行代码尝试更改只读内存存储的字符串'Linux'。此操作当然行不通所以才会造成崩溃。

10、Process that changes its own name

问:你能否写一个程序在它运行时修改它的名称?

答:以下代码可以完成

#include<stdio.h>

int main(int argc, char *argv[])
{
  int i = 0;
  char buff[100];

  memset(buff,0,sizeof(buff));

  strncpy(buff, argv[0], sizeof(buff));
  memset(argv[0],0,strlen(buff));

  strncpy(argv[0], "NewName", 7);

  // Simulate a wait. Check the process
  // name at this point.
  for(;i<0xffffffff;i++);

  return 0;
}

11、局部变量的返回地址

问:下面的代码有问题吗?如果有,如何修改?

#include<stdio.h>

int* inc(int val)
{
 int a = val;
 a++;
 return &a;
}

int main(void)
{
  int a = 10;

  int *val = inc(a);

  printf("\n Incremented value is equal to [%d] \n", *val);

  return 0;
}

答:虽然上面的代码有时运行会很好,但是在方法 inc() 中有很严重的隐患。当inc()方法执行后,再次使用局部变量的地址就会造成不可估量的结果。解决之道就是传递变量a的地址给main()。

12、处理 printf() 参数

问:以下代码输出请问是什么?

#include<stdio.h>

int main(void)
{
  int a = 10, b = 20, c = 30;

  printf("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2));

  return 0;
}

答:输出将是

110..40..60

这是因为参数都是从右向左处理的,然后打印出来却是从左向右。

(0)

相关推荐

  • C语言实现堆排序的简单实例

    本文通过一个C语言实现堆排序的简单实例,帮助大家抛开复杂的概念,更好的理解堆排序. 实例代码如下: void FindMaxInHeap(int arr[], const int size) { for (int j = size - 1; j > 0; --j) { int parent = j / 2; int child = j; if (j < size - 1 && arr[j] < arr[j+1]) { ++child; } if (arr[child] &

  • 基于C语言实现五子棋游戏完整实例代码

    本文实例讲述了基于C语言实现五子棋游戏的方法,代码备有比较完整的注释,可以帮助读者更好的加以理解. 五子棋游戏代码如下: /* * 使用键盘的上下左右键移动棋盘,空格键表示下棋,ESC键退出程序 */ #include <stdio.h> #include <stdlib.h> #include <bios.h> #include <graphics.h> #include<malloc.h> /* * 对应键盘键的十六进制数字 */ #defi

  • c语言实现多线程动画程序示例

    该程序是利用opengl图形库与fmod音频库写的一个简单3d动画程序.该程序在vs下运行良好,若缺少相关dll文件请确认已配制fmod与opengl库. mixmodel.cpp 复制代码 代码如下: // mixmodel.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h" //定义一个线程DWORD WINAPI SoundProc( LPVOID LPVIDEOPARAMETERS);//光照变量GLfloat  whiteLight[] =

  • javascript 扫雷游戏

    "); for (var i = 0; i "); for(var j = 0; j   "); buffer.append(" "); } buffer.append(" "); var workarea = document.getElementById("workarea"); workarea.innerHTML = buffer.toString(); mine(); // lay mines at the

  • js版扫雷实现代码 原理不错

    效果图:以下代码复制粘贴到记事本后保存为.html文件,打开后会出现提示,右击允许即可: 寻雷-----by 魅月 var data=new Array( [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0

  • C语言对堆排序一个算法思路和实现代码

    算法思想简单描述: 堆排序是一种树形选择排序,是对直接选择排序的有效改进. 堆的定义如下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆.在这里只讨论满足前者条件的堆. 由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项.完全二叉树可以很直观地表示堆的结构.堆顶为根,其它为左子树.右子树. 初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的

  • C语言实现顺序表基本操作汇总

    本文汇总了C语言下实现及操作顺序表的方法,对于学习数据结构的朋友来说是一个不错的参考程序.完整代码如下: #include<stdio.h> #include<stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 typedef int status ;

  • 基于C语言实现的扫雷游戏代码

    本文详细讲述了基于C语言实现的扫雷游戏代码,代码中备有比较详细的注释,便于读者阅读和理解.希望对学习游戏开发的朋友能有一点借鉴价值. 完整的实例代码如下: /* 模拟扫雷游戏 */ #include <graphics.h> #include <math.h> #include <stdio.h> #include <dos.h> #include <stdlib.h> #include <conio.h> #include <

  • 基于C语言实现的贪吃蛇游戏完整实例代码

    本文以实例的形式讲述了基于C语言实现的贪吃蛇游戏代码,这是一个比较常见的游戏,代码备有比较详细的注释,对于读者理解有一定的帮助. 贪吃蛇完整实现代码如下: #include <graphics.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #define NULL 0 #define UP 18432 #define DOWN 20480 #define LEFT 19200 #defi

  • 12个关于C语言的有趣问答

    本文汇总了12个关于C语言的问答,对于加深对C语言程序设计的难点理解很有帮助,读者可参考一下: 1.gets() 方法 问:以下代码有个被隐藏住的问题,你能找到它吗? 答:这个不显眼的问题就是使用了 gets() 方法.此方法接受一个string类型参数,但是却没有检测此数值是否 有足够的空间来拷贝数据.所以这里我们一般用 fgets() 方法将来的更好. #include<stdio.h> int main(void) { char buff[10]; memset(buff,0,sizeo

  • Python语言编写智力问答小游戏功能

    本篇博文将使用Python代码语言简单编写一个轻松益智的小游戏,效果如下所示: 1.设计思路 本项目使用SQLite建立问答题库,每道题包括4个选项答案(3个正确答案,1个错误答案).每道题都有一定分值,根据用户的答题效率,自动计算出最后的答题成绩. 2.建立题库 使用SQLite数据库建立题库,本质上就是SQL语句,创建exam表,实现代码如下所示: #导入SQLite驱动 import sqlite3 # 连接到SQLite数据库,数据库文件是test.db # 如果文件不存在,会自动在当前

  • C语言链表实现贪吃蛇游戏

    阅读学习了源代码,并做了简单的注释和修改,里面只用了链表数据结构,非常适合C语言入门者学习阅读. 程序可在VS2013下编译运行. #include<stdio.h> #include<time.h> #include<windows.h> #include<stdlib.h> #define U 1 #define D 2 #define L 3 #define R 4 //蛇的状态,U:上 :D:下:L:左 R:右 typedef struct SNAK

  • 解析Java中的默认方法

    为什么有默认方法? Java 8 就要来临,尽管发布期限已经被推迟, 我们仍非常确信在它最终发布的时候会支持lambdas 表达式. 前面提到过,我们之前关于这个主题已经讨论了不少,不过,lambdas表达式并不是Java 8中唯一改变的游戏规则. 假设Java 8 已经发布并且包含了lambda.现在你打算用一下lambda,最明显的应用场景莫过于对collection的每一个元素应用lambda. List<?> list = - list.forEach(-); // 这就是lambda

  • 一文详解Golang中的切片数据类型

    目录 含义 定义 三个要素 切片与数组的区别 示例代码 切片内存分布 切片定义分类 数组生成切片 示例代码 切片索引 直接声明切片 定义语法 代码示例 使用make定义切片 常用操作 长度计算 容量计算 判断是否为空 切片追加 语法格式 尾部追加 开始位置追加 中间位置追加 复制 引用和复制 切片的删除 删除开头 删除中间 删除结尾 指定位置 排序 迭代器 含义 切片是一个种特殊的数组.是对数组的一个连续片段的引用,所以切片是一个引用类型.切片可以是数组中的一部分,也可以是由起始和终止索引标识的

  • C语言将24小时制转换为12小时制的方法

    本文实例讲述了C语言将24小时制转换为12小时制的方法.分享给大家供大家参考.具体实现方法如下: /* * 24小时制转换为12小时制 */ #include <stdio.h> int main() { int n, m; printf("Enter a 24-hour time:"); scanf_s("%d:%d",&n,&m); if (n < 0) { printf("Error1!\n"); syst

  • 使用C语言实现12种排序方法

    1.冒泡排序 思路:比较相邻的两个数字,如果前一个数字大,那么就交换两个数字,直到有序. 时间复杂度O(n^2),稳定性:这是一种稳定的算法. 代码实现: void bubble_sort(int arr[],size_t len){ size_t i,j; for(i=0;i<len;i++){ bool hasSwap = false; //优化,判断数组是否已经有序,如果有序可以提前退出循环 for(j=1;j<len-i;j++){ //这里j<len-i是因为最后面的肯定都是最

  • C语言完整实现12种排序算法(小结)

    目录 1.冒泡排序 2.插入排序 3.折半插入排序 4.希尔排序 5.选择排序 6.鸡尾酒排序 7.堆排序 8.快速排序 9.归并排序 10.计数排序 11.桶排序 12.基数排序 1.冒泡排序 思路:比较相邻的两个数字,如果前一个数字大,那么就交换两个数字,直到有序.时间复杂度O(n^2),稳定性:这是一种稳定的算法.代码实现: void bubble_sort(int arr[],size_t len){ size_t i,j; for(i=0;i<len;i++){ bool hasSwa

  • c语言实现24小时制转换为12小时制示例

    分别用三个函数:输入(time_input).输出(time_output).转换(time_change)函数 复制代码 代码如下: #include<iostream>#include<cstdlib>using namespace std;void time_input(int& hour,int& minute);void time_output(int& hour,int& minte,char& noon);void time_c

  • Python语言的12个基础知识点小结

    python编程中常用的12种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序.去重,字典排序,字典.列表.字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化输出,进制转换,Python调用系统命令或者脚本,Python 读写文件. 1.正则表达式替换 目标: 将字符串line中的 overview.gif 替换成其他字符串 复制代码 代码如下: >>> line = '<IMG ALIGN="middle" SRC=\'#\'

随机推荐