看看你的C语言到底什么水平吧

绝对能够测试你的C语言功力的几个问题!

很少有真正精通了C语言编程的学员,一般都有或多或少概念不是完全清楚的问题,特别是一些需要丰富的实战经验才能体会和明白的问题,如字符串,指针,类型转换,定义指向函数的指针类型,这也是导致学习C困难的一个原因。下面有几个简单测试将能发现你对C语言的掌握情况。
1)int x=35;
   char str[10];
//问:strlen(str)和sizeof(str)的值分别是多少?

答:strlen(str) 值不确定,strlen根据‘/0‘确定字符串是否结束。
 sizeof(str)=10 sizeof一个数组为数组长度

strcpy(str,"www.it315.org"/*共13个字母*/);
//问:此时x和strlen(str)的值分别是多少?

答:x 为35
    strcpy(char* dest, const char* src)
    根据src来复制dest,依照src的‘/0‘决定复制的长度,而dest必须要提供足够的长度,这里会引起溢出,strlen返回13,但是数组外部的数据已经被破坏

strlen的值为13,在VC++环境下,x的值是要改变的(其他编译器下没试,).虽然表面上看来,在程序中并没有修改x的值,但是实际运行的结果是上面的x的值发生了修改,这是因为strcpy以后,把多余的数据拷贝进了str的邻居(int类型的x)中,所以x的数据也就变了.这是一个曾让我刻骨铭心的问题,在我刚出道时遇到这个问题,虽然在朋友的帮助下解决了这个问题,但一直不明白x的值为何变了,只有最后走上培训教师的岗位,才开始梳理自己曾经的困惑,才开始总结以前的经验供学员们借鉴.我觉得这个题目的价值非常之大,它能引起学员对字符串拷贝越界问题的足够重视,并且通过这个问题更能明白字符串的处理是怎么回时,更能明白字符串与字符数组的关系:字符串就是一个字符数组,只是把这个字符数组用在处理串的函数中时,这些函数不考虑数组的长度,只是记住数组的首地址,从首地址开始处理,并在遇到0时结束处理,

3)char str[10];
str="it315.org";

//编译能通过吗?

答:数组不能赋值,只能初始化。char str[10] = "it315.org";
而且初始化时编译器会检查数组的长度与初始化串的长度是否匹配

4)char *pstr;
   strcpy(pstr,"http://www.it315.org");
//上句编译能通过吗?运行时有问题吗?

答:可以通过编译,但是pstr指向了常量区,运行时最好只做读操作,写操作不保险。

编译可以通过,但是pstr没有进行有效的初始化,它指向了一个不确定的内存区,运行时会出现内存不可写错误!

const char *p1;
char * const p2;   //const指针必须初始化
//上面两句有什么区别吗?

答:const char* 和 char const* 一样,都是表示指向常量的字符指针。
char * const 表示指向字符的常量指针

p1=(const char *)str;
//如果是p1=str;编译能够通过吗?明白为什么要类型转换?类型转换的本质是什么?

答:可以通过编译。关于常量与非常量指针的关系是这样的:
   const指针可以指向const或者非const区域,不会造成什么问题。
   非const指针不能指向const区域,会引起错误。(呵呵,这个问题,很经典)

strcpy(p1,"abc");//编译能够通过吗?

答:不能通过,strcpy( char*, const char*); char* 不能指向const char*

注意:非const指针不能指向const区域,会引起错误。

printf("%d",str);//有问题吗?

答:没有问题,输出的是str的地址信息

Char *pstr;
pstr=3000;//编译能过吗?如果不行,该如何修改以保证编译通过呢?

答:不能通过,char* pstr表示pstr是个字符指针,不能指向3000的整形变量。
 修改的话,可以这样:pstr = (char*)3000,把pstr指向3000这个地址;

long y=(long)pstr;//可以这样做吗?

答:可以,y的值为pstr所指的地址。不过如果是纯粹要地址的话,最好是用unsigned long。

int *p=str;
*p=0x00313200;
printf("%s",str);//会是什么效果?提示0x31对应字符‘1‘,0x32对应字符‘2‘。

答:首先编译未必会过关,有些编译器可能不允许int * 直接指向char*。最好是改为int *p = (int*)str;
过关了效果就是什么东西都没有。int *p=str; p为str所指的地址,*p表示修改了str所指向的内存。

由于sizeof(int)在32位机上,int有4个字节(其实具体要看编译器的配置文件,好像是limit.h,一般是4个字节)所以修改了str[0]-str[3]
由于0x00313200头尾都是0,所以字符串为‘/0‘开头,什么都打印不出来。这里有个Big-endin和little-endin的问题。以0x31323334为例
little-endin的机器上面,0x31323334在内存中排列顺序为34 33 32 31,输出为4321,如INTEL芯片的pc
big-endin机器上面为31 32 33 34 ,输出为1234,如IBM POWERPC

p=3000;//p+1的结果会是多少?

答:3000+sizeof(int); 指针+1均为原来地址加上sizeof(指针所指的数据类型)

char *pc=new char[100];//上述语句在内存中占据几个内存块,怎样的布局情况?

答: 本身pc会占用函数栈一个4字节的指针长度(具体是否为4个字节要看机器和编译器)。
 new会在堆上申请100个字节sizeof(char)的连续空间。

void test(char **p)
{
       *p=new char[100];
}//这个编译函数有问题吗?外面要调用这个函数,该怎样传递参数?

答:该程序没有问题。需要在函数中对指针所指的地址进行变化是必须传入指针的地址。
  原因是这样的:如果传入的为指针本身,在函数调用的时候,实参会被复制一个实例,这   样就不是原来的指针了,对该指针本身进行的任何改变都不能传递回去了。
  可以这样理解,如果传入的参数为int,那么对int本身的值的改变就传不回去啦,加个*也是一样的。

//能明白typedef int (*PFUN)(int x,int y)及其作用吗?
答:定义了一个函数指针类型的宏,这样PFUN就表示指向返回值为int,且同时带2个int  参数的函数指针类型了。
 可以用来定义这样的变量:
 比如有个函数为int fun( int x, int y );

PFUN p = fun;

补充::函数指针最大的用处在于它可以被一个模板方法调用,这是我在学java的设计模式时领悟到的.例如,有两个函数的流程结构完全一致,只是内部调用的具体函数不同,如下所示:
void func1()
{
         //一段流程代码和面向方面的代理,如安全检查,日志记录等
         int sum = add( x , y);
        //一段流程代码和面向方面的代理,如安全检查,日志记录等
}
void func2()
{
         //与func1完全相同的一段流程代码和面向方面的代理,如安全检查,日志记录等
         int difference = sub( x , y);
        //与func1完全相同的一段流程代码和面向方面的代理,如安全检查,日志记录等
}
那么,可以只定义一个函数,如下所示
void func(PFUNC p)
{
         //与func1完全相同的一段流程代码和面向方面的代理,如安全检查,日志记录等
         int difference = p( x , y);
        //与func1完全相同的一段流程代码和面向方面的代理,如安全检查,日志记录等
}
调用程序在调用时,让参数p分别指向add和sub函数就可以了.

对于许多类似的问题一般从书本上是看不到的,不通过大量的实践与调试是难以理解和令人困惑的,所以在本文中对于类似上述的C语言问题都将作出详细的解释和讲解。

时间: 2024-10-12 20:45:05

看看你的C语言到底什么水平吧的相关文章

C语言到底怎么了?

自2015年11月开始,所有C语言系列都呈现出衰落之势.在超过15年的时间里,C语言在编程语言排行榜中的占比一直有15%-20%,但今年却突然急转直下,目前占比已不足10%,且目前看来回天乏力. 那么,C语言到底怎么了?数月前,我们已经列出了一些可能的原因,比如:在构思诸如移动应用或者移动网页等热门领域类项目时,我们很少想要使用C语言:这么多年来,C语言都没有太大优化,也没有大型企业支持推进这门语言的发展——不过,也许原因不仅于此,我们将继续探寻更多原因,同时希望大家分享自己的看法. 编程语言排

全方位分析易语言值得学吗,谈易语言到底好学吗

第一个问题,易语言值得学吗? 首先,要探讨易语言值得学吗.我们要先了解易语言,易语言是一门全中文且可视化的编程语言,由吴涛开发. 我们先来看下易语言的界面 1.易语言的愿意是让编程变的简单易学关于这一点.就有很多人有意见了.有人评论说:易语言的错误在于立志于解决一个不存在的问题,并引以为豪.不会英语在业界没有人权,就是这样.相信这样说的人.一般是文化程度较高的人.且英语水平可以.但是对于学历不高.英语水平不高的人的人来说.评论是这样的.下面是一位学历不高的人对易语言的评价从小就喜欢编程,试过自学

C语言到底怎么分配空间

程序分为:代码区.数据区.bss区.堆区.栈区.平时常用区分的是代码区.堆区.栈区.下面加上例子区分一下. 3 代码区顾名思义就是存放代码的,里面的内容是不可以修改的.例如你定义了一个变量char *buff = "abcdef";这个char型指针指向了代码区,这个指针里面的数据只可以被读取不可以别修改,因为指针指向了代码区,如果你继续往这个指针里面放东西,会报段错误.例如:buff[1] = 'a',这样会报错,段错误.因为上面已经将buff指向了代码区,代码区的数据是不可以改变的

为什么和其他语言相比C语言是快速的语言

初入门的我们经常听见别人说"真正的程序员用C语言编程,C是最快的语言因为它是最靠近及其底层的语言."那么和其他语言相比C语言到底有什么特别的呢? C语言没有什么特别,这就是它快速的秘诀. 新的语言支持更多的特性,比如,垃圾回收(garbage collection),动态类型(dynamic typing)等等.这些新加入的特性让出学者们更容易上手. 问题的关键就在于,这些新的功能增加了处理开销(processing overhead),也就降低了程序性能.而C语言中没有这些功能,它不

让你提前认识软件开发(24):C语言的发展历史和主要特点

第1部分 重新认识C语言 C语言的发展历史和主要特点 作为一门众所周知的计算机编程语言,C语言是谁发明的呢?它是如何演进的?它有何特点?到底有多少人在使用它? 1. C语言之父 C语言是1972年由美国贝尔实验室的计算机科学家Dennis Ritchie(丹尼斯·里奇)设计发明的.因此,Dennis Ritchie被誉为"C语言之父"(他已于2011年10月9日去世,享年70岁).图1中的人物就是Dennis Ritchie. 图1 "C语言之父" Dennis R

Go将统治下一个10年?Go语言发展现状分析

"本文是国内Go语言大中华区首席布道师--许式伟,在QCon2015上海站上的分享.他预测Go语言10年内一定会超过C和java,并且统治这一个10年. Go语言语法及标准库变化 Go从1.0版本到现在(2015年)已经有三年多的时间,大的版本发布了五个,下面大家一起看看每个大版本分别都改了什么,当然这里不可能把所有的细节都提到,但我认为重要的会提出来. 首先是Go1.1,Go1.0于2012年4月发布,此后基本维持了每半年发布一个新版本的时间间隔.Go1.5比较例外,在Go1.5的拖累下,Go

kotlin, 一种新的android平台一级开发语言

最近看到一则科技新闻, 大致内容是google将kotlin语言作为android应用开发的一级语言, 与java并驾齐驱, 这是一个开发界的大事件大新闻, 连google的亲儿子go语言也没有这种待遇, 而kotlin貌似名不见经传,之前根本连听都没听说过. 这让我对kotlin产生了极大的好奇心,这种能让得到google如此宠幸的语言到底是何方神圣? 在网上查了相关资源后, 对kotlin有了粗略的了解. kotlin是一种jvm平台语言, kotlin编译器会将kotlin代码转换成jvm

R语言基础编程技巧汇编 - 前言

前 言 R语言是近年来迅速崛起的用于数据分析和数据挖据的编程语言,它由一批统计学家开发,进而广泛应用于各种需要进行统计分析的行业.在大数据时代,其优雅的编码风格.包罗万象的开发包.强大的数据处理能力,吸引了来自各个领域从事数据分析相关工作的人员. R语言是强大自由的,但是其学习曲线也是陡峭的.本人具有C/C++,C#,Python等多种语言的开发经验,就本人的体会,从R语言初级开发水平进阶到中级开发水平,要比其他编程语言更加困难,往往很多初学者就在这个阶段放弃了,相当可惜.另外,对于大量没有很多

JAVA语言对比C++语言的几个优点和自身的关键特性

之所以写这篇博客不是为了比较JAVA语言和C++语言到底孰优孰劣,而是从语言本身出发进行对比总结程序编码设计上的差别.因水平有限,某些内容可能太过片面,欢迎指正和讨论. JAVA语言在设计上很好地借鉴了C++语言,是一种完全“面向对象”的编程语言.JAVA语言的语法与C++语言的结构语法非常相似,这使得C++程序猿学习JAVA变得非常容易. JAVA语言的最大优点就是“Wirte Once,Run Everywhere”,就是“一次编写,到处运行”的意思.JAVA语言相对C++来说,增加了一些新