提示:这里“零值”可以是0, 0.0 , FALSE 或者“空指针”。
例如int 变量n 与“零值”比较的if 语句为:
if ( n == 0 )
if ( n != 0 )
以此类推。
(1)请写出bool flag 与“零值”比较的if 语句:
【标准答案】if ( flag ) if ( !flag )
(2)请写出float x 与“零值”比较的if 语句:
【标准答案】 const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
不可将浮点变量用“==” 或“!=” 与数字比较,应该设法
转化成“>=” 或“<=” 此类形式。
(3)请写出char *p 与“零值”比较的if 语句
【标准答案】 if (p == NULL) if (p != NULL)
char str[] = “Hello” ;
char *p = str ;
int n = 10;
请计算
(1)sizeof (str ) = (2)sizeof ( p ) =
(3)sizeof ( n ) =
(4)void Func ( char str[100])
{
…… ;
}
请计算sizeof( str ) =
(5)void * p = malloc( 100 );
请计算sizeof ( p ) =
【标准答案】
(1)6(2)4 (3 )4 (4)4(5)4
typedef union {long i; int k[5]; char c;} DATE;
struct data { int cat; DATE cow; double dog;} too;
DATE max;
typedef union
{
long i;
int k[5];
char c;
}DATE;
struct data
{
int cat;
DATE cow;
double dog;
}too;
DATE max;
则语句printf(“%d”,sizeof(struct date)+sizeof(max)); 的
执行结果是:_____
【标准答案】DATE是一个union, 变量公用空间. 里面最
大的变量类型是int[5], 占用20个字节. 所以它的大小是
20
data 是一个struct, 每个变量分开占用空间. 依次为int4 +
DATE20 + double8 = 32.
所以结果是20 + 32 = 52.
当然… 在某些16位编辑器下, int 可能是2字节,那么结果
是int2 + DATE10 + double8 = 20
int main()
{
char a;
char *str=&a;
strcpy(str,“hello”);
printf(str);
return 0;
}
【标准答案】没有为str分配内存空间,将会发生异常
问题出在将一个字符串复制进一个字符变量指针所指
地址。虽然可以正确输出结果,但因为越界进行内在
读写而导致程序崩溃。
char* s=“AAA”;
printf(“%s”,s);
s[0]=‘B’;
printf(“%s”,s);
有什么错?
【标准答案】“AAA” 是字符串常量。s是指针,指向这个
字符串常量,所以声明s的时候就有问题。
cosnt char* s=“AAA”;
然后又因为是常量,所以对是s[0] 的赋值操作是不合法
的。
【标准答案】int (*s[10])(int) 函数指针数组,每个指针
指向一个int func(intp aram) 的函数。
【标准答案】c和c++ 中struct的主要区别是c中的struct不可以含有成员函数,而c++ 中的struct可以。
c++ 中struct和class的主要区别在于默认的存取权限不同,struct默认为public ,而class默认为private
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,“hello world”);
}
int main( )
{
char *str=NULL;
getmemory(str);
printf(“%s/n”,str);
free(str);
return 0;
}
【标准答案】程序崩溃,getmemory中的malloc 不能返回动态内存,free ()对str操作很危险。
char szstr[10];
strcpy(szstr,"0123456789");
【标准答案】长度不一样,出现段错误。
数组:数据顺序存储,固定大小;
链表:数据可以随机存储,大小可动态改变
void main()
{
char aa[10];
printf(“%d”,strlen(aa));
}
sizeof()和初不初始化,没有关系,
strlen()和初始化有关,打印结果值未知。
struct A
{
char t:4;
char k:4;
unsigned short i:8;
unsigned long m;
};
【标准答案】8
struct name1
{
char str;//1--2
short x;//2
int num;//4
} ;
【标准答案】8
struct name2
{
char str;//1 -- 4
int num;//4
short x;//2 -- 4
};
【标准答案】12
wap( int* p1,int* p2 )
{
int * p; //(int)malloc(4); is ok
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
【标准答案】p 为野指针(指向一个已删除的对象或未申请访问受限内存区域的指针)
【标准答案】(void )ptr 和((void**))ptr 值是相同的
【标准答案】*((void (*)( ))0x100000 ) ( );
首先要将0x100000强制转换成函数指针,即:
(void (*)())0x100000
然后再调用它:
*((void (*)())0x100000)();
https://blog.csdn.net/qq_17242957/article/details/50628309
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
答:程序崩溃。
因为GetMemory 并不能传递动态内存,
Test 函数中的 str 一直都是 NULL。
strcpy(str, “hello world”);将使程序崩 溃。—因为str没有空间
char *GetMemory(void)
{
char p[] = "hello world"; //char *p="hello world"可以,p是局部变量,但是*p不是常量区的数据。
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
字符串是不可直接返回的,因此没用所谓的返回"hello world"之类的说法,你只能返回字符串的首地址。
当你用char p[]方式定义时,系统在堆栈上创建一个临时数组,然后把hello world内容拷贝进去,因此当你返回p时,实际是返回那个临时数组的首地址。
改成指针以后,p实际指向的是一个常量字符串"hello world",而这个字符串是在常量区永远存在的,不是临时变量。可以这么说,p是局部变量,但是*p不是
请问运行Test 函数会有什么样的结果?
答:可能是乱码。
因为GetMemory 返回的是指向“栈内存”
的指针,该指针的地址不是 NULL,但其原
现的内容已经被清除,新内容不可知。
void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
printf("*p=%p\n", *p);//------------------地址1
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
printf("str=%p\n", str); //------------------地址2 == 地址1
strcpy(str, "hello");
printf(str);
}
请问运行Test 函数会有什么样的结果?
答:
(1)能够输出hello
(2)内存泄漏 //没有释放
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str != NULL)
{
strcpy(str, “world”);
printf(str);
}
}
请问运行Test 函数会有什么样的结果?
答:篡改动态内存区的内容,后果难以预 料,非常危险。
因为free(str);之后,str 成为野指针,
free(str);之后要加上 str=NULL
if(str != NULL)语句不起作用
答:因为你首先要理解一点.内存空间不是你分配了才可以使用
只是你分配了之后使用才安全,为什么要进行对他初始化呢
因为,如果你没对他初始化,而引用这个指针并却其指向的内存进行修改
因为指针未被初始化,所以指针所指向的也是随机的,他是个野指针,如果你引用指针,并修改这个指针所指向的内容,而如果这个指针所指向的内容恰好是另外一个程序的数据的话,你将其进行修改了,就会导致另外一个程序可能不能正常运行了.所以使用前一定要进行初始化
答:意思是说,强指针变量置空,初始化为NULL,使它不指向任何内容,这样引用她也不会出现上面的问题
总之一点,记住在使用指针之前要对它进行初始化操作就可以了
子。
【参考答案】一个定义为volatile的变量是说这变量可
能会被意想不到地改变,这样,编译器就不会去假设
这个变量的值了。精确地说就是,优化器在用到这个
变量时必须每次都小心地重新读取这个变量的值,而
不是使用保存在寄存器里的备份。
下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量
(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
volatile对应的变量可能在你的程序本身不知道的情况下发生改变
比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量
你自己的程序,是无法判定何时这个变量会发生变化
还比如,他和一个外部设备的某个状态对应,当外部设备发生操作的时候,通过驱动程序和中断事件,系统改变了这个变量的数值,而你的程序并不知道。
对于volatile类型的变量,系统每次用到他的时候都是直接从对应的内存当中提取,**而不会利用cache当中的原有数值,**以适应它的未知何时会发生的变化,系统对这种变量的处理不会做优化——显然也是因为它的数值随时都可能变化的情况。
————————————————
版权声明:本文为CSDN博主「乌克兰水晶小乳猪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/didi1663478999/article/details/98523122
【参考答案】这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast )为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下:
int * ptr;
ptr= (int *)0x67a9;
*ptr = 0xaa55;
【标准答案】防止该头文件被重复引用。
【标准答案】对于#include
对于#include “filename.h” ,编译器从用户的工作路径开始搜索filename.h 。
【标准答案】:
(1)可以定义const 常量
(2)const 可以修饰函数的参数、返回值,甚至函数的定义体。
被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
【标准答案】
【标准答案】没有回收垃圾资源。
【标准答案】可以用引用头文件的方式,也可以用extern 关键字。
两者区别:
如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变量写错了,那么在编译期间会报错,
如果你用extern 方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
【标准答案】可以,在不同的C 文件中以static形式来声明同名全局变量。
可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。
https://blog.csdn.net/basstal/article/details/52275191
从技术上来说,声明不会有链接属性,因为声明不会在可执行映像中分配存储空间;因此,不存在链接器是否容许交叉引用那些存储空间的问题。
当把(所谓的)全局变量global定义为static时,由于static使定义的变量称为内部链接,所以在各个.c文件中,存在多个同名global但不同等的定义,每个翻译单元中的global维持自己的内存区域,此时链接器不会报告“符号被多重定义”错误。
此时,(所谓的)全局变量并没有达到一般意义上全局变量的效果,相当于每个翻译单元的局部变量。
【标准答案】队列先进先出,栈后进先出。
【标准答案】Heap是堆,stack是栈。
Stack的空间由操作系统自动分配/释放,Heap上的空
间手动分配/释放。
Stack空间有限,Heap是很大的自由存储区
C 中的malloc 函数分配的内存空间即在堆上,C++中对应的是new 操作符。
程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行。
【标准答案】
#define swap(x, y) (x)=(x)+(y);(y)=(x)–(y);(x)=(x)–(y);
【标准答案】#define Min(X, Y) ((X)>(Y)?(Y):(X))// 结尾没有 ;
【标准答案】
带参宏 带参函数
处理时间 编译时 运行时
参数类型 无 需定义
程序长度 变长 不变
占用存储空间 否 是
运行时间 不占运行时间 调用和返回时占
实参如果是表达式容易出问题
#define S(r) r*r
area=S(a+b);//第一步换为area=r*r;,第二步被换为area=a+b*a+b;
正确的宏定义是#define S(r) ((r)*(r))
(2)宏名和参数的括号间不能有空格
(3)宏替换只作替换,不做计算,不做表达式求解
(4)函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内存
(5)宏的哑实结合不存在类型,也没有类型转换。
(6)宏展开使源程序变长,函数调用不会
(7)宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值。
【标准答案】提示编译器对象的值可能在编译器未监测到的情况下改变。
int main()
{
int x=3;
printf("%d",x);
return 1;
}
【标准答案】mian中,c标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息。
【标准答案】
#define NTBL(table) (sizeof(table)/sizeof(table[0]))
【标准答案】static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。
他们都放在静态数据区,但是编译器对他们的命名是不同的。
如果要使变量在其他模块也有意义的话,需要使用extern 关键字。
关于Static、全局变量、局部变量、Extern之间的种种
【标准答案】 static全局变量只初使化一次,防止在其他文件单元中被引用;
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。
这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
static全局变量只初使化一次,防止在其他文件单元中被引用;
【标准答案】static局部变量只被初始化一次,下一次依据上一次结果值;
把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
static局部变量只被初始化一次,下一次依据上一次结果值
【标准答案】static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static修饰的函数),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件.
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。
(1)先来介绍它的第一条也是最重要的一条:隐藏。
当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。
下面是a.c的内容
char a = ‘A’; // global variable
void msg()
{
printf(“Hello\n”);
}
下面是main.c的内容
int main(void)
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
程序的运行结果是:
A Hello
你可能会问:为什么在a.c中定义的全局变量a和函数msg能在main.c中使用?前面说过,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。此例中,a是全局变量,msg是函数,并且都没有加static前缀,因此对于另外的源文件main.c是可见的。
如果加了static,就会对其它源文件隐藏。例如在a和msg的定义前加上static,main.c就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。Static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用。
(2)static的第二个作用是保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。虽然这种用法不常见,但我还是举一个例子。
#include
int fun(void){
static int count = 10; // 事实上此赋值语句从来没有执行过
return count–;
}
int count = 1;
int main(void)
{
printf(“global\t\tlocal static\n”);
for(; count <= 10; ++count)
printf(“%d\t\t%d\n”, count, fun());
return 0;
}
程序的运行结果是:
global local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
(3)static的第三个作用是默认初始化为0。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵,我们可以一个一个地把所有元素都置0,然后把不是0的几个元素赋值。如果定义成静态的,就省去了一开始置0的操作。再比如要把一个字符数组当字符串来用,但又觉得每次在字符数组末尾加’\0’太麻烦。如果把字符串定义成静态的,就省去了这个麻烦,因为那里本来就是’\0’。不妨做个小实验验证一下。
#include
int a;
int main(void)
{
int i;
static char str[10];
printf("integer: %d; string: (begin)%s(end)", a, str);
return 0;
}
程序的运行结果如下
integer: 0; string: (begin)(end)
最后对static的三条作用做一句话总结。首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0。
以上内容出自博客园Mr. Write之手,写的相当清晰易懂,存档方便复习。原文地址:http://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。
全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。
这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态
的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。
由于静态全局变量的作用域局限于一个源文件内,只
能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使
用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。
Extern与Static:
首先,我要告诉你static与extern是一对“水火不容”的家伙,也就是说extern和static不能同时修饰一个变量;其次,static修 饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义了;最后,static修饰全局变量的作用域 只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,其他编译单元则看不到它,如:
test1.h:
#ifndef TEST1H
#define TEST1H
static char g_str[] = "123456";
void fun1();
#endif
test1.cpp:
#include "test1.h"
void fun1()
{
cout << g_str << endl;
}
test2.cpp
#include "test1.h"
void fun2()
{
cout << g_str << endl;
}
以上两个编译单元可以连接成功, 当你打开test1.obj时,你可以在它里面找到字符串"123456", 同时你也可以在test2.obj中找到它们,它们之所以可以连接成功而没有报重复定义的错误是因为虽然它们有相同的内容,但是存储的物理地址并不一样, 就像是两个不同变量赋了相同的值一样,而这两个变量分别作用于它们各自的编译单元。
也许你比较较真,自己偷偷的跟踪调试上面的代码,结果你发现两个编译单元(test1, test2)的g_str的内存地址相同,于是你下结论static修饰的变量也可以作用于其他模块,但是我要告诉你,那是你的编译器在欺骗你,大多数编 译器都对代码都有优化功能,以达到生成的目标程序更节省内存,执行效率更高,当编译器在连接各个编译单元的时候,它会把相同内容的内存只拷贝一份,比如上 面的"123456", 位于两个编译单元中的变量都是同样的内容,那么在连接的时候它在内存中就只会存在一份了, 如果你把上面的代码改成下面的样子,你马上就可以拆穿编译器的谎言:
test1.cpp:
#include "test1.h"
void fun1()
{
g_str[0] = 'a';
cout << g_str << endl;
}
test2.cpp
#include "test1.h"
void fun2()
{
cout << g_str << endl;
}
void main()
{
fun1(); // a23456
fun2(); // 123456
}
这个时候你在跟踪代码时,就会发现两个编译单元中的g_str地址并不相同,因为你在一处修改了它,所以编译器被强行的恢复内存的原貌,在内存中存在了两份拷贝给两个模块中的变量使用。
正是因为static有以上的特性,所以一般定义static全局变量时,都把它放在原文件中而不是头文件,这样就不会给其他模块造成不必要的信息污染,同样记住这个原则吧!
【标准答案】程序的局部变量存在于栈(stack) 中,全局变量存在于静态数据区中,动态申请数据存在于**堆(heap)**中。
【标准答案】
C语言中的三大预编译功能包括:宏定义、文件包含、条件编译。
1、总是使用不经常改动的大型代码体。
2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
C语言中的三大预编译功能
【参考答案】设2个栈为A,B, 一开始均为空.
入队:
将新元素push入栈A;
出队:
(1)判断栈B 是否为空;
(2)如果不为空,则将栈A中所有元素依次pop 出并push到栈B;
(3)将栈B的栈顶元素pop 出;
【标准答案】c用宏定义,c++ 用inline(内联)
【参考答案】
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)
printf("SECONDS_PER_YEAR=%ul\n", SECONDS_PER_YEAR);
例如,思考一下下面的例子:
#define dPS struct s *
typedef struct s * tPS;
以上两种情况的意图都是要定义dPS 和tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?
【参考答案】这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:typedef 更好。
思考下面的例子:
dPS p1,p2; 第一个扩展为---- struct s * p1, p2;
tPS p3,p4;
上面的代码定义p1为一个指向结构的指针,p2为一个实际的结构,这也许不是你想要的。
第二个例子正确地定义了p3 和p4 两个指针。
【标准答案】C++ 语言支持函数重载,C 语言不支持函数重载。
函数被C++ 编译后在库中的名字与 C 语言的不同。
假设某个函数的原型为:void foo(int x, int y);
该函数被C 编译器编译后在库中的名字为_foo ,而C++ 编译器则会产生_foo_int_int之类的名字。
C++提供了C 连接交换指定符号extern“C”来解决名字匹配问题。
for (i=0; i<N; i++)
{
if (condition)
DoSomething();
else
DoOtherthing();
}
if (condition)
{
for (i=0; i<N; i++)
DoSomething();
}
else
{
for (i=0; i<N; i++)
DoOtherthing();
}
【标准答案】
优点:程序简洁
缺点:多执行了N-1次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。
优点:循环的效率高
缺点:程序不简洁
【标准答案】死循环,和while(1)相同。
【标准答案】前一个循环一遍再判断,后一个判断以后再循环。
#include
int main()
{
int a,b,c,d;
a=10;
b=a++; //b=10, a=11
c=++a; //c=12, a=12
d=10*a++; //d=120, a=13
printf("b,c ,d:%d,%d,%d",b,c,d );
return 0;
}
【标准答案】10,12,120
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
请问、
p1+5= ;
p2+5= ;
【标准答案】0x801005、0x810020
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
printf("p1=%x, p1+5=%x\n", p1, p1+5);
printf("p2=%x, p2+5=%x\n", p1, p2+5);
p1=801000, p1+5=801005
p2=801000, p2+5=810014
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int*)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
请问输出:
【标准答案】2,5
int a[5]={1,2,3,4,5};
int * ptr=(int*)(&a+1);
//此时a作为数组的首地址,+1的跨度为整个数组的长度,ptr指向数组a后面的空间地址。
printf(“%d,%d”,*(a+1),*(ptr-1));
//a+1代表a1, *a1指向2, (ptr-1)代码a数组的最后一个元素的地址。
a[0], a1, a2, a3, a4, ptr
printf(“&a=%p\n”, &a);
printf(“&a[0]=%p\n”, &a[0]);
printf(“&a1=%p\n”, &a1);
printf(“&a2=%p\n”, &a2);
printf(“&a3=%p\n”, &a3);
printf(“&a4=%p\n”, &a4);
printf(“ptr=%p\n”, ptr);
&a=0028FF10
&a[0]=0028FF10
&a1=0028FF14
&a2=0028FF18
&a3=0028FF1C
&a4=0028FF20
ptr=0028FF24
int a[60][250][1000],i,j,k;
for(k=0;k<1000;k++)
for(j=0;j<250;j++)
for(i=0;i<60;i++)
a[i][j][k]=0;
【标准答案】把循环语句内外换一下。
(编译的时候没错,运行的时候出错,但这个数组太大,如果放在栈中,还是会溢出,要作为全局变量)
https://www.cnblogs.com/ios8/p/ios-c-test.html iOS求职之C语言面试题
#define SQUARE(a)((a)*(a))
int a=5;
int b;
b=SQUARE(a++);
【标准答案】宏在预编译时会以替换的形式展开,仅仅会替换。涉及到宏的地方,不要用++ - - ,标准中对此没有规定,因此最终结果将会依赖于不同的编译器。
执行程序的答案可能是25、也有可能是36。
dev-c++,windows下为b=25,a=7
#define Max_CB 500
void LmiQueryCSmd(StructMSgCB * pmsg)
{
unsigned char ucCmdNum;
......
for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)
{
......;
}
}
【标准答案】死循环
unsigned char //无符号字符型表示范围0~255
char // 有符号字符型 表示范围-128~127
【标准答案】while(1){}或者for(;
int modifyvalue()
{
return(x+=10);
}
int changevalue(int x )
{
return(x+=1);
}
void m ain()
{
int x =10;
x++; //x=11
changevalue(x);
x++; //x=12
modifyvalue();
printf("First output:%d\n",x);
x++;//x=13
changevalue(x);
printf("Second output:%dn",x);
modifyvalue();
printf("Thirdoutput:%dn",x);
}
输出?
【标准答案】12、13、13
【标准答案】switch 的参数不能为实型。得是整型
#include<stdio.h>
main()
{
int a,b,c,d;
a=10;
b=a++; //b=10, a=11
c=++a; //c=12, a=12
d=10*a++;//d=120, a = 13
printf("b,c ,d:%d,%d,%d",b,c,d );
return 0;
}
【标准答案】10,12,120
【参考答案】 void main()
{
int a;
scanf(“%d”,&a);
printf(“%c”,(a)&(a-1)?’n’:’y’); // 若是打印y,否则n
}
这导致了很多编译开发商提供一种扩展—让标准C 支持中断。具代表事实是,产生了一个新的关键字
__interrupt 。下面的代码就使用了__interrupt 关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。
__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf(" Area = %f", area);
return area;
}
【参考答案】这个函数有太多的错误了,以至让人不知从何说起了:
1). ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用的。
2). ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。
3). 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR 中做浮点运算。此外,ISR 应该是短而有效率的,在ISR 中做浮点运算是不明智的。
4). 与第三点一脉相承,printf() 经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b> 6)? puts("> 6") : puts("<= 6");
}
【参考答案】这个问题测试你是否懂得C 语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答案是输出是“>6” 。原因是当表达式中存在有符号类型和无符号类型时所有的数都自动转换为无符号类型。因此-20 变成了一个非常大的正整数,所以该表达式计算出的结果大于6 。这一点对于应当频繁用到无符号数据类
型的嵌入式系统来说是丰常重要的。如果你答错了这个问题,你也就到了得不到这份工作的边缘。
printf(“b=%u\n”, b); //b=4294967276
a+b = 6+(-20) = 6 + 4294967276 = 4294967282
unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
/*1‘s complement of zero */
【参考答案】对于一个int型不是16位的处理器为说,上面的代码是不正确的。应编写如下:
unsigned int compzero = ~0;
这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里,好的嵌入式程序员非常准确地明白硬件的细节和它的局限,然而PC机程序往往把硬件作为一个无法避免的烦恼。
到了这个阶段,应试者或者完全垂头丧气了或者信心满满志在必得。如果显然应试者不是很好,那么这个测试就在这里结束了。但如果显然应试者做得不错,那么我就扔出下面的追加问题,这些问题是比较难的,我想仅仅非常优秀的应试者能做得不错。提出这些问题,我希望更多看到应试者应付问题的方法,而不是答案。不管如何,你就当是这个娱乐吧…
unsigned int zero = 0;
unsigned int compzero1 = 0xFFFF;
unsigned int compzero2 = ~0;
printf(“compzero1=%u\n”, compzero1);
printf(“compzero2=%u\n”, compzero2);
compzero1=65535
compzero2=4294967295
char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
puts("Gota null pointer");
else
puts("Gota valid pointer")
;
【参考答案】这个你可以先大胆猜测下,然后再用你的编译器尝试着编译下~~
char cc=‘a’;
char *ptr;
ptr = &cc;
printf(“ptr=%p, *ptr=%c\n”, ptr,*ptr);
if ((ptr = (char *)malloc(0)) == NULL)
puts(“Gota null pointer”);
else
puts(“Gota valid pointer”);
printf(“ptr=%p, *ptr=%c\n”, ptr,*ptr);
ptr=0028FF2F, *ptr=a
Gota valid pointer
ptr=00381720, *ptr=`
malloc(0)后,ptr地址发生变更
欢迎进入C语言程序笔试面试,编写程序代码单元。
已知strcpy 函数的原型是 char *strcpy(char *strDest,
const char *strSrc);其中strDest是目的字符串,strSrc 是源字符串。
(1)不调用C++/C 的字符串库函数,请编写函数
strcpy 。
(2)strcpy 能把 strSrc 的内容复制到strDest,为什
么还要char * 类型的返回值?
https://blog.csdn.net/okawari_richi/article/details/57411796 strcpy()函数详解
char * strcpy(char *dst,const char *src)
{
if((dst==NULL)||(src==NULL))
return NULL;
char *ret = dst; //[1]
while ((*dst++=*src++)!='\0'); //[2]
return ret;//[3]
}
(1)const 修饰:源字符串参数用const修饰,防止修改源字符串;
(2)空指针检查:源指针和目的指针都有可能会出现空指针的情况,所以应该对其进行检查;
(3)为什么要设置ret 指针以及返回ret指针的位置3,由于目的指针dst已经在进行移动了,所以用辅助指针ret表明首指针;
(4)以上所示2处,为简单的字符串的复制过程,正好表明strcpy函数遇到’\0’将会停止
【参考答案】
int binary_search(int* arr, int key, int n)
{
int low=0;
int mid;
int high=n-1;
while(low<=high)
{
mid = (low+high)/2;
if(key < arr[mid])
{
high=mid-1;
}
else if(key>arr[mid])
{
low=mid+1;
}
else
{
return mid;
}
}
return -1;
}
int main(int argc, char *argv[])
{
if(1)
{
int it[] = {0,1,2,3,4,5,6,7};
int index = binary_search(it, 7, 8);
printf("index=%d\n", index); //index=7
}
return 0;
}
【参考答案】
unsigned int TestAsOne1(char log)
{
int i;
unsigned int num=0, val;
for(i=0; i<8; i++)
{
val = log >> i; // 移位
val &= 0x01; // 与1 相与
if(val)
num++;
}
return num;
}
【参考答案】
int Invert(char* str) //此实现不能处理负数和非数字的字符串
{
int num =0;
while(*str!='\0')
{
int d igital=*str-48;
num=num*10+digital;
str=str+1;
}
return num;
}
int Invert2(char* str)
{
if(str==NULL)
return -1;
int num=0, negFlag=0;
if(str[0] == '-')
{
negFlag=1;
str++;
}
while(*str!='\0')
{
if(*str>='0' && *str<='9')
{
num = num*10 + (*str-'0');
}
else
{
num=-1;
break;
}
str++;
}
if(negFlag)
num *= -1;
return num;
}
int main(int argc, char *argv[])
{
if(1)
{
char *str1="1234";
int str_i1= Invert2(str1);
printf("str1=%s, str_i1=%d\n", str1, str_i1);
char *str2="-1234";
int str_i2= Invert2(str2);
printf("str2=%s, str_i2=%d\n", str2, str_i2);
char *str3="-12s4";
int str_i3= Invert2(str3);
printf("str3=%s, str_i3=%d\n", str3, str_i3);
}
return 0;
}
/*
str1=1234, str_i1=1234
str2=-1234, str_i2=-1234
str3=-12s4, str_i3=1
*/
【参考答案】
void IntToCharChange(int num, char* pval) //此实现,转换负数有问题
{
char strval[100];
int i , j;
int val0 = 0;
int val1 = 0;
val0 = num;
for(i=0; i<100; i++)
{
val1 = val0 % 10; //取余
val0 = val0 / 10; // 取整
strval[i] = val1 + 48; // 数字—字符
if(val0 < 10)
{
i++;
strval[i] = val0 + 48;
break;
}
}
for(j=0; j<=i; j++) // 倒置
pval[j] = strval[i-j];
pval[j] = '\0';
}
void IntToCharChange1(int num, char* pval)
{
//判断正负号
char negFlag=0;
if(num<0)
{
negFlag=1;
}
//计算字符串长度
int len=0;
int tmp_num=num;
if(negFlag)
{
tmp_num *= -1;
len++;
}
while(tmp_num>0)
{
len++;
tmp_num /= 10;
}
cout << "len=" << len << endl;
//转成字符串
tmp_num = num;
if(negFlag)
{
tmp_num *= -1;
pval[0] = '-';
}
int val;
int i=0;
while(tmp_num>0)
{
val = tmp_num%10;
pval[len-i-1]= val+'0';
tmp_num=tmp_num/10;
i++;
}
pval[len] = '\0';
}
int main(int argc, char *argv[])
{
if(1)
{
int num1 = 1234;
char *str1;
IntToCharChange1(num1, str1);
cout << str1 << endl;
int num2 = -1234;
char *str2;
IntToCharChange1(num2, str2);
cout << str2 << endl;
}
return 0;
}
/*
len=4
1234
len=5
-1234
*/
【参考答案】
int mystrcmp(const c har* str1, const char* str2)
{
assert((str1 != NULL) && (str2 != NULL));
int ret = 0;
while (!(ret = *(unsigned char*)str1 - * (unsigned char*)str2) && *str2)
{
str1++;
str2++;
}
if (ret > 0)
ret = 1;
else if (ret < 0)
ret = -1;
return ret;
}
//str1和str2可以是字符串常量或者字符串变量,返回值为整形。返回结果如下规定:
//①str1小于str2,返回负值或者-1(VC返回-1);②str1等于str2,返回0;
//③str1大于str2,返回正值或者1(VC返回1);
int mystrcmp(const char* str1, const char* str2)
{
assert((str1 != NULL) && (str2 != NULL));
int ret=0;
while((ret=*(unsigned char*)str1-*(unsigned char*)str2)==0 && *str2)
{
str1++;
str2++;
}
if (ret > 0)
ret = 1;
else if (ret < 0)
ret = -1;
return 0;
}
int main(int argc, char *argv[])
{
if(1)
{
char *str1="hellod";
char *str2="hello";
int res = mystrcmp1(str1, str2);
cout << res << endl;
}
return 0;
}
【参考答案】
void AntitoneValue(char* father, char* child)
{
int i ;
char source[100];
int j = 0;
while(father[j]) //放入source ,[j] 为长度
{
source[j] = father[j];
j++;
if(j > 99)
return;
}
source[j] = '\0';
for(i=0; i<j; i++)
child[i] = source[j-i-1]; // 反序
child[i] = '\0';
}
void AntitoneValue(char* father, char* child)
{
if(father == NULL)
return;
int len = strlen(father);
int i;
for(i=0; i<len; i++)
{
child[i]=father[len-i-1];
}
child[len]='\0';
}
int main(int argc, char *argv[])
{
if(1)
{
char *str1="dongj1223";
char str2[100];
AntitoneValue(str1, str2);
cout << str2 << endl;
}
return 0;
}
//3221jgnod
【参考答案】
int s earch(char* cpSource, intn , char ch) // 起始地址,搜索长度,目标字符
{
int i;
for(i=0; i<n && *(cpSource+i) != ch; ++i);
return i;
}
int search(char* cpSource, int n , char ch) // 起始地址,搜索长度,目标字符
{
int res;
int i;
for(i=0; i<n && *(cpSource+i)!=ch; i++)
{
; //不相等,则继续;相等则退出;超出范围也退出;
}
if(i==n)
res = -1; //考虑找不到的情况,返回-1
else
res = i; //找到,则返回索引值
return res;
}
【参考答案】
int C hildString(char*p) // 自己写
{
char *q =p;
int s tringlen=0, i=0,j=1,len=0,maxlen=1;
while(*q!=’\0’) //不能用strlen, 求得长度stringlen
{
Stringlen++;
q++;
}
while( i< String len )
{
if(*(p+i)==*(p+j)& & j< St ri ngle n )
{
len++; // 统计子串长度
i++;
j++;
}
else
{
if(len>maxlen) // 统计最大子串长度
{
maxlen=len+1;
len=0;
}
else
len=0;
i++;
j++;
}
}
retu rn ma xlen;
}
int ChildString(char*p) // 自己写
{
char *q = p;
int strlen = 0;
while(*q != '\0') //不能用strlen, 求得长度stringlen
{
strlen++;
q++;
}
int i, sublen=1, maxlen=0;
for(i=0; i<strlen; i++)
{
if(*(p+i)==*(p+i+1) && (i+1<strlen))
{
sublen++; // 统计子串长度
}
else
{
if(sublen > maxlen) // 统计最大子串长度
{
maxlen = sublen;
}
sublen = 1;
}
}
return maxlen;
}
int main(int argc, char *argv[])
{
if(1)
{
char *str = "hellllo";
int len = ChildString(str);
cout << len << endl;
}
return 0;
}
【参考答案】答:用两个指针来遍历这个单向链表,第一个指针p1,每次走一步;第二个指针p2,每次走两步;当p2 指针追上p1的时候,就表明链表当中有环路了。
int testLinkRing(Link *head)
{
Link *t1=head,*t2=head;
while( t1->next && t2->next)
{
t1 = t1->next;
if (NULL == (t2 = t2->next->next))
return 0; // 无环
if (t1 == t2)
return 1;
}
return 0;
}
int testLinkRing1(Link *head)
{
Link *t1=head,*t2=head;
while( t1->next && t2->next)
{
t1 = t1->next;
if (NULL == (t2 = t2->next->next))
return 0; // 无环
if (t1 == t2)
return 1;
}
return 0;
}
int testLinkRing2(Link *head)
{
Link *slow=head, *fast=head;
while(fast->next && fast->next->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast) //相遇则有环
return 1;
}
return 0;
}
Link *getLinkRingNode(Link *head)
{
Link *slow=head, *fast=head;
while(fast->next && fast->next->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast) //相遇则有环
{
printf("slow's val = %d\n", slow->val);
break;
}
}
if(fast->next==NULL || fast->next->next==NULL)
return NULL;
slow=head;
while(slow != fast)
{
slow=slow->next;
fast=fast->next;
}
return slow;
}
int main(int argc, char *argv[])
{
if(1)
{
Link *node1 = (Link*)malloc(sizeof(Link));
node1->val=1;
node1->next=NULL;
Link *node2 = (Link*)malloc(sizeof(Link));
node2->val=2;
node2->next=NULL;
Link *node3 = (Link*)malloc(sizeof(Link));
node3->val=3;
node3->next=NULL;
Link *node4 = (Link*)malloc(sizeof(Link));
node4->val=4;
node4->next=NULL;
node1->next=node2;
node2->next=node3;
node3->next=node4;
node4->next=node2;
int res1 = testLinkRing1(node1);
int res2 = testLinkRing2(node1);
printf("testLinkRing1=%d, testLinkRing2=%d\n", res1, res2);
Link *ring_node = getLinkRingNode(node1);
if(ring_node)
printf("ring_node->val=%d\n", ring_node->val);
else
printf("ring_node is null\n");
}
return 0;
}
/*
testLinkRing1=1, testLinkRing2=1
slow's val = 4
ring_node->val=2
*/
【参考答案】
void BubbleSort(double a rr[], int n)
{
int i,j ;
int e xchange = 1 ;// 交换标志
for(i=1;i<n;i++)
{ // 最多做n-1趟排序
exchange=0 ;// 本趟排序开始前,交换标志应为假
for(j=n-1;j>=i ;j--) //对当前无序区R[i..n]自下向上扫描
if(arr[j+1] > arr [ j])
{// 交换记录
arr[0]=arr[j+1];//R[0]不是哨兵,仅做暂存单元
arr[j+1]=arr[j];
arr[j]=arr[0];
exchange=1 ;// 发生了交换,故将交换标志置为真
}
if(!exchange) // 本趟排序未发生交换,提前终止算法
return ;
} //endfor(外循环)
}
void BubbleSort(double arr[], int n)
{
int i,j;
int swapFlag=0;
for(i=0; i<n-1; i++)
{
swapFlag=0;
for(j=0; j<n-i-1; j++)
{
if(arr[j]< arr[j+1])
{
double temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
swapFlag=1;
}
}
if(swapFlag==0)
break;
}
}
int main(int argc, char *argv[])
{
if(1)
{
double arr[5]={3.1,2.3,5.6,4.1,1.2};
BubbleSort(arr, 5);
int i=0;
for(i=0; i<5; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
return 0;
}
void merge(double arr[], int start, int center, int end, int n)
{
int mid=center+1;
double tmp_arr[n];
printf("start=%d, end=%d, length=%d\n", start, end, n);
//double *tmp_arr=(double*)malloc(5 * sizeof(double));
int start_backup=start;
int tmp_index=start;
while(start<=center && mid<=end)
{
if(arr[start] >= arr[mid])
{
tmp_arr[tmp_index++] = arr[start++];
}
else
{
tmp_arr[tmp_index++] = arr[mid++];
}
}
while(start<=center)
{
tmp_arr[tmp_index++] = arr[start++];
}
while(mid<=end)
{
tmp_arr[tmp_index++] = arr[mid++];
}
for(tmp_index=start_backup; tmp_index<=end; tmp_index++)
{
arr[tmp_index] = tmp_arr[tmp_index];
}
//while(start_backup<=end)
//{
//arr[start_backup] = tmp_arr[start_backup++];
//}
}
void sort(double arr[], int start, int end, int n)
{
if(start<end)
{
int center = (start+end)/2;
sort(arr, start, center, n);
sort(arr, center+1, end, n);
merge(arr, start, center, end, n);
}
}
void mergeSort(double arr[], int n)
{
int start=0;
int end=n-1;
sort(arr, start, end, n);
}
int main(int argc, char *argv[])
{
if(1)
{
double arr[5]={3.1,2.3,5.6,4.1,1.2};
//BubbleSort(arr, 5);
mergeSort(arr, 5);
int i=0;
for(i=0; i<5; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
return 0;
}
/*
start=0, end=1, length=5
start=0, end=2, length=5
start=3, end=4, length=5
start=0, end=4, length=5
5.6 4.1 3.1 2.3 1.2
*/
【参考答案】
// 删除操作
Status ListDelete_DuL(DuLinkList &L,inti,Ele mType &e)
{
if(!(p=G e tElemP_DuL(L,i))) return ERROR;
e=p->data;
p->prior->next=p->next;
p->next->prior=p->pror;
free(p);
return OK;
}
// 插入操作
Status ListInsert_DuL(DuLinkList &L,inti,ElemType &e)
{
if(!(p=G e tElemP_DuL(L,i)))
return ERROR;
if(!(s=(DuLinkList)malloc(sizeof(DuLNode))))
return ERROR;
s->data=e;
s->pri or =p;
p-> next -> prior =s;
p->next=s;
s->next=p->next->next;
return OK;
}
【参考答案】从第一个元素开始,ps指向他,将他(
ps)指向头节点(ps->next = head) ,将ps设为头节点
(head = ps; )操作下一个元素(ps= pe->next;)等
于是依次将每个元素翻到原头节点前面。
void reverse(test* head)
{
test* pe = head;
test* ps = head->next;
while(ps)
{
pe->next = ps->next;
ps->next = head;
head = ps;
ps = pe->next;
}
}
typedef struct Node{
int val;
struct Node *next;
}Link;
Link* reverse(Link *head)
{
if(head==NULL || head->next==NULL)
return head;
Link *pcur=head, *pnew=NULL, *prev=NULL, *pnext=NULL;
while(pcur)
{
pnext=pcur->next;
if(pnext==NULL)
{
pnew=pcur;
printf("pnew's head=%d\n", pnew->val);
}
pcur->next=prev;
prev=pcur;
pcur=pnext;
}
return pnew;
}
Link* reverse2(Link* head)
{
if(head==NULL || head->next==NULL)
return head;
Link* prev = head;
Link* pnext = head->next;
while(pnext)
{
prev->next = pnext->next;
pnext->next = head;
head = pnext;
pnext = prev->next;
}
return head;
}
int main(int argc, char *argv[])
{
if(1)
{
Link *node1 = (Link*)malloc(sizeof(Link));
node1->val=1;
node1->next=NULL;
Link *node2 = (Link*)malloc(sizeof(Link));
node2->val=2;
node2->next=NULL;
Link *node3 = (Link*)malloc(sizeof(Link));
node3->val=3;
node3->next=NULL;
Link *node4 = (Link*)malloc(sizeof(Link));
node4->val=4;
node4->next=NULL;
node1->next=node2;
node2->next=node3;
node3->next=node4;
//node4->next=node2;
Link *head=node1;
printf("原始链表:\n");
while(head)
{
printf("%d ", head->val);
head=head->next;
}
printf("\n");
head=node1;
head = reverse(head);
//head = reverse2(head);
printf("翻转链表:\n");
while(head)
{
printf("%d ", head->val);
head=head->next;
}
printf("\n");
}
return 0;
}
/*
原始链表:
1 2 3 4
pnew's head=4
翻转链表:
4 3 2 1
*/
【参考答案】
#include
main()
{ int a [2][3]={{1,2,3},{4,5,6}};
int b[3][2],i,j;
printf("array a :\n");
for(i=0;i<=1;i++)
{ for(j=0;j<=2;j++)
{ printf("%5d",a[i][j]);
b[j][i]=a[i][j];
}
printf("\n");
}
printf("array b :\n");
for(i=0;i<=2;i++)
{ for(j=0;j<=1;j++)
printf("%5d",b[i][j]);
printf("\n");
}
}
//二维数组行列元素互换,存到另一个数组中
void convertArry()
{
int a[2][3]={{1,2,3},{4,5,6}};
int b[3][2];
int i,j;
printf("a:\n");
for(i=0; i<2; i++)
{
for(j=0; j<3; j++)
{
printf("%d ", a[i][j]);
b[j][i]=a[i][j];
}
printf("\n");
}
printf("b:\n");
for(i=0; i<3; i++)
{
for(j=0; j<2; j++)
{
printf("%d ", b[i][j]);
}
printf("\n");
}
}
【参考答案】
#include
main()
{
char str i ng[81];
int i,num=0,word=0;
char c;
gets(string);
for(i=0;(c=string[i])!='\0';i++)
if(c==' ')
word=0;
else if(word==0)
{
word=1; num++; }
printf("There are %d word s in the line\n",num);
}
//输入一行字符,统计其中有多少个单词。
int words(char *arr)
{
int words = 0;
int prev_is_char=0;
int pcur_is_char=0;
while(*arr != '\0')
{
if((*arr>='a' && *arr <='z') || (*arr>='A' && *arr<='Z'))
{
pcur_is_char=1;
}
if(prev_is_char==0 && pcur_is_char==1)
{
words++;
}
prev_is_char = pcur_is_char;
pcur_is_char = 0;
arr++;
}
return words;
}
int words2(char *arr)
{
int i,num=0,word=0;
char c;
for(i=0;(c=arr[i])!='\0';i++)
{
if(c==' ')
word=0;
else if(word==0)
{
word=1;
num++;
}
}
return num;
}
int main(int argc, char *argv[])
{
if(1)
{
char *str="hello, world, china** i love you!!";
int count = words(str); //保证了单词必须是字母
printf("count=%d\n", count);
int count2 = words2(str); //含有"1234"的错认为是单词
printf("count2=%d\n", count2);
char *str1="hello, 1234, world, china** i love you!!";
count = words(str1); //保证了单词必须是字母
printf("count=%d\n", count);
count2 = words2(str1); //含有"1234"的错认为是单词
printf("count2=%d\n", count2);
}
return 0;
}
/*
count=6
count2=6
count=6
count2=7
*/
候本版讨论的那个问题。
【参考答案】
void* m e mcpy(void* pvTo, const void* pvFrom, size_t size)
{
assert((pvTo != NULL) && (pvFrom ! = NULL));
byte* pbTo= pvTo;
byte* pbFrom = pbFrom;
while (size-- > 0)
{
*pbTo++ = *pbFrom++;
}
return pvTo;
}
https://blog.csdn.net/Wilsonboliu/article/details/7919773
void* my_memcpy(void* dest, void* src,size_t n)
{
if(destNULL || srcNULL)
return NULL;
void* ret = dest;
unsigned char* str1 = (unsigned char*)dest;
unsigned char* str2 = (unsigned char*)src;
while (n--)
{
*str1++ = *str2++;
}
return ret;
}
void* my_memmove(void* dest, void* src, size_t n)
{
if(destNULL || srcNULL)
return NULL;
void* ret = dest;
unsigned char* str1 = (unsigned char*)dest;
unsigned char* str2 = (unsigned char*)src;
if(str1 > str2)
{
while(n--)
{
*(str1+n)=*(str2+n);
}
}
else
{
while(n--)
{
*str1++ = *str2++;
}
}
return ret;
}
char *strcat1(char *dest, const char *src) //将源字符串加const,表明其为输入参数
{
assert((dest!=NULL) && (src!=NULL));
char *ret = dest;
while(*dest)
{
dest++;
}
while(*dest++=*src++);
return ret;
}
char *strcpy2(char *dest, const char *src)
{
assert((dest!=NULL)&&(src!=NULL));
char *ret = dest;
while(*dest++=*src++);
return ret;
}
char *strcpy1(char *strDest,const char *strSrc)
{
if((strDestNULL)||(strSrcNULL))
return NULL;
char *ret = strDest; //[1]
while ((*strDest++=*strSrc++)!='\0'); //[2]
return ret;//[3]
}
int strcmp1 (const char *str1,const char *str2)
{
assert((str1!=NULL) && (str2!=NULL));
//assert((str1 != ‘\0’) && (str2 != ‘\0’));
while(*str1 && *str2 && (*str1==*str2))
{
str1++;
str2++;
}
return *str1-*str2;
}
int strlen1(const char *str)
{
if(str==NULL)
return 0;
int len=0;
while(*str++ != ‘\0’)
{
len++;
}
return len;
}
int main(int argc, char *argv[])
{
if(1)
{
char str1[100]={“i love”};
char str2[50]={“China”};
//printf(“%s\n”,strcat1(str1,str2));
//printf(“%s\n”,strcpy1(str1,str2));
//printf(“%d\n”,strcmp1(str1,“”));
printf(“%d\n”,strlen1(str2));
}
if(0)
{
int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, sizeof(arr1));
int i;
for (i = 0; i < 10; i++)
{
printf(“%d “, arr2[i]);
}
printf(”\n”);
int arr3[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
my_memmove(arr3 + 5, arr3 + 4, 3 * sizeof(int));
for (i = 0; i < 10; i++)
{
printf("%d ", arr3[i]);
}
printf("\n");
}
return 0;
}
92、有1、2、3 、4个数字,能组成多少个互不相同且
无重复数字的三位数?都是多少?
【参考答案】
#inc lude “stdio.h”
#include “conio.h”
main()
{
int i,j,k;
printf(“\n”);
for(i=1;i<5;i++) /* 以下为三重循环*/
for(j=1;j<5;j++)
for (k=1;k<5;k++)
{
if (i!=k&&i!=j&&j!=k) /* 确保i、j、k三位互不相同*/
pr intf(“%d,%d,%d\n”,i,j,k);
}
getch();
}
93、取一个整数a从右端开始的4~7位。
【参考答案】
main()
{
unsigned a,b,c,d;
scanf(“%o”,&a);
b=a>>4;
c=(0<<4);
d=b&c;
printf(“%o\n%o\n”,a,d);
}
//取一个整数a从右端开始的4~7位
void getNumsRight()
{
char str[50]={0};
int len=0;
unsigned int num=12345678;
char val;
while(num>0)
{
val = num%10;
num = num/10;
str[len]=val+‘0’;
len++;
}
printf(“num str = %s\n”, str);
int i;
for(i=3; i<7; i++)
{
printf("%c", str[i]);
}
printf("\n");
}
int main(int argc, char *argv[])
{
if(1)
{
getNumsRight();
}
return 0;
}
/*
num str = 87654321
5432
*/
94、打印出杨辉三角形(要求打印出10行如下图)。
【参考答案】
main()
{
int i,j;
int a [10][10];
printf(“\n”);
for(i=0;i<10;i++)
{
a[i][0]=1;
a[i][i]=1;
}
for(i=2;i<10;i++)
for(j=1;j a[i][j]=a[i-1][j-1]+a[i-1][j];
for(i=0;i<10;i++)
{
for(j=0;j<=i;j++)
printf(“%5d”,a[i][j]);
printf(“\n”);
}
getch();
}
void yanghuiTriangle(int M)
#define PYRAMID // 金字塔,会额外填充空格
// #define REVERSE // 反向再来一次,得到菱形
{
int a [M][M], i, j; // 二维数组和循环变量,a[行][列]
for (i = 0; i
#ifdef PYRAMID
for (j = 0;j <= M-i; j++)
printf (" ");
#endif // 填充结束
for (j = 0; j <= i; j++) // 赋值打印
{
if(i == j || j == 0)
{
a[i][j] = 1;
}
else
{
a[i][j] = a[i-1][j] + a[i-1][j-1]; // 使用上一行计算
}
printf("%4d", a[i][j]);
}
printf("\n");
}
void yanghui(int M)
{
int i,j;
int a [M][M];
printf("\n");
//for(i=0;i<10;i++)
//{
//a[i][0]=1;
// a[i][i]=1;
//}
for(i=0;i
}
int main(int argc, char *argv[])
{
if(1)
{
yanghui(10);
}
return 0;
}
95、实现strcmp 函数。
100 条经典 C语言笔试题目
96、写一个函数,求一个字符串的长度,在main函数
中输入字符串,并输出其长度。
【参考答案】
main()
{
intlen;
char *s tr[20];
printf(“please input a string:\n”);
scanf(“%s”,str);
len=length(str);
printf(“the s tring has %d characters.”,len);
getch();
}
length§
char *p;
{
int n ;
n=0;
while(*p!=‘\0’)
{
n++;
p++;
}
return n;
}
97、809*??=800*??+9*??+1 其中??代表的两位数
,8*?? 的结果为两位数,9*??的结果为3位数。求??代
表的两位数,及809*??后的结果。
【参考答案】output(long b,long i)
{
printf(“\n%ld/%ld=809*%ld+%ld”,b,i,i,b%i);
}
main()
{
long int a ,b,i;
a=809;
for(i=10;i<100;i++)
{
b=ia+1;
if(b>=1000&&b<=10000&&8i<100&&9*i>=100)
output(b,i);
}
getch();
}
98、某个公司采用公用电话传递数据,数据是四位的整数,在
传递过程中是加密的,加密规则如下:每位数字都加上5, 然后
用和除以10的余数代替该数字,再将第一位和第四位交换,第
二位和第三位交换。
【参考答案】
main()
{
int a ,i,aa4,t;
scanf( " % d " ,&a) ;
aa[0]=a %10;
aa1=a %100/10;
aa2=a %1000/100;
aa3=a /1000;
for(i=0 ; i<=3 ;i++)
{
aa [i]+=5;
aa[i] %=10;
}
for(i=0;i<=3/2;i++)
{
t=aa[i];
aa[i]= aa[3- i];
aa[3- i]= t ;
}
for(i=3;i>=0;i–)
prin tf("% d ", a [i]);
getch();
}
99、计算字符串中子串出现的次数。
【参考答案】
main()
{
char str1[20],str2[20],*p1,*p2;
int sum=0;
printf(“please input two strings\n”);
scanf(“%s%s”,str1,str2);
p1=str1;p2=str2;
while(*p1!=‘\0’)
{
if(*p1==*p2)
{
while(*p1==*p2&&*p2!=‘\0’)
{
p1++;
p2++;
}
}
else
p1++;
if(*p2==‘\0’)
sum++;
p2=str2;
}
printf(“%d”,sum);
getch();
}
100 、有两个磁盘文件A和B, 各存放一行字母,要求把
这两个文件中的信息合并(按字母顺序排列),输出
到一个新文件C 中。
【参考答案】
100 条经典 C语言笔试题目
main()
{
FILE *fp;
in t i,j,n,ni;
char c[160],t,ch;
if((fp=fopen(“A”,“r “))==NULL)
{
printf(“file A cannot be opened\n”);exit(0);
}
printf(”\nA contents are :\n”);
for(i=0;(ch=fgetc(fp))!=EOF ; i++)
{
c[i]=ch;pu tchar(c[i]);
}
fclose(fp);
ni=i;
if((fp=fopen(“B”,“r “))==NULL)
{
printf(“file B cannot be opened\n”);exit(0);
}
printf(”\nB contents are :\n”);
for(i=0;(ch=fgetc(fp))!=EOF ; i++)
{
c[i]=ch;pu tchar(c[i]);
}
fclose(fp);
n=i;
for(i=0;i
printf(“\nC file is:\n”);
fp =f open(“C”,“w”);
for(i=0;i
getch();
}
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC
语法后生成一个完美的目录。
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' |
‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" |
“Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash |
– is en-dash, — is em-dash |
一个具有注脚的文本。2
Markdown将文本转换为 HTML。
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
我们依旧会支持flowchart的流程图:
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
mermaid语法说明 ↩︎
注脚的解释 ↩︎