//6******************************************************
//构造 N 个结点的单链表返回链表头指针,要求链表中各结点顺序
//与结点数据输入顺序相反,例如输入 1,2,3,4,5,形成的链表为
//head->5 4 3 2 1 ,补充程序
#define N 10
typedef struct Node
{
int data;
struct Node*next;
}NODE;
int Get_Data(int i);//定义省略
Node*Create_u()
{
int i;
NODE*p,*Head=NULL;
for(i=0;iData=Get_Data(i);
_____???????___________;
________________;
}
return Head;
}
//7**********************************************
//N 个结点链表,每个结点中存放一个字符,判断链表存放的字符是否
//中心对称,即 a b c c b a 或 a b c b a,补充程序
typedef struct Node
{
int data;
struct Node*next;
}NODE;
bool Is_symmeic(NODE*head,*int n)
{
char D[N];
int i,d;
_____?????_____;
for(i=0;idata;
head=head->next;
}
if(_____head!=NULL???_____)
{
head=head->next;
}
while(head)
{
_______________;
if(D[i]!=head->data)
{
return false;
}
head=head->next;
}
return true;
}
//8*************************************
//str 中只含有大写和小写字母函数 change_move(char*str)将字符串中大写改成*
并
//移到前面小写后返回*的个数
//如 AabBdcYY 改为*****abd,返回 5
int chang_move(char*str)
{
int len,i,curstr=-1;
len=strlen(str);
for(i=len-1;i>=0;i--)
{
if(str[i]>='A'&&str[i]<='Z')
{
str[i]='*';
if(cursor==-1)
{
cursor=i;
}
else if(cursor>i)
{
_____________;
str[i]='*';
_____________;
}
}
return____________;
}
//9***********************************************
//求两个字符串的第一个公共子串,并返回该子串
//如:"a b c d e f g e h i" "a a c d e f * * g e h i"
//第一个为"c d e f";不许用 strcmp()
char*Maxf(char*str1,char*str2)
{
}
3.二维数组空间的动态申请
a.简单的,已经有一维,如
char (*c)[5];
c=new char[n][5];//n 为已定义的行数
b.二维的
int **p;
p=new int*[m_row];//创建行指针
for(int i=0;i
#i nclude
#i nclude
char *getstring(void)
{
char p[]="hello everyone";
return p;
}
char *getmemory(void)
{
return (char *)malloc(10);
}
int main(int argc, char* argv[])
{
char *p=getmemory();
strcpy(p,"helloworld");
printf("%s",p);
printf("%s",getstring());
return 0;
}
这个主要是 char p[]前少一个 static...
题二:
读程序,写出运行结果
#i nclude
#i nclude
#i nclude
#i nclude
typedef struct
{
int value;
char type;
}head_t;这是什么东西啊?
typedef struct
{
head_t head;
int para;
}message_t;
void main(void)
{
message_t *message=NULL;
head_t *head=NULL;
message=(message_t *)malloc(sizeof(message_t));
assert(message);//测试的条件不成立则终止程序
memset(message,0,sizeof(message_t));
message->para=100;
message->head.type='a';
head=(head_t *)message;
head->value++;
head->type++;
printf("message->head.value=%d,message->head.type=%c,message->para=%d\n",me
ssage->head.value,message->head.type,message->para);
" free(message);
return;
}
#include
#include
using namespace std;
class Student {
public:
Student() {}
Student( const string& nm, int sc = 0 )
void set_student( const string& nm, int sc = 0 )
{
: name( nm ), score( sc ) {}
name = nm;
score = sc;
return name;
}
const string& get_name() const
{
}
int get_score() const
{
}
return score;
private:
string name;
int score;
};
// output student's name and score
void output_student( const Student& student )
{
cout << student.get_name() << "\t";
cout << student.get_score() << endl;
}
int main()
{
Student stu( "Wang", 85 );
output_student( stu );
}
设 计了一个类 Student,数据成员有 name 和 score,有两个构造函数,有一个设
置 成 员 数 据 函 数 set_student() , 各 有 一 个 取 得 name 和 score 的 函 数
get_name() 和 get_score()。请注意 get_name() 和 get_score() 后面都加了
const,而 set_student() 后面没有(也不能有 const)。
首先说一点题外话,为什么 get_name() 前面也加 const。如果没有前后两个 const
的话,get_name() 返回的是对私有数据成员 name 的引用,所以通过这个引用可
以改变私有成员 name 的值,如
Student stu( "Wang", 85 );
stu.get_name() = "Li";
cout << student.get_name() << "\t"; // 如 果 get_name() 和
cout << student.get_score() << endl;
即把 name 由原来的 "Wang" 变成了 "Li",而这不是我们希望的发生的。所以在
get_name() 前面加 const 避免这种情况的发生。
那么,get_name() 和 get_score() 这两个后面应该加 const 的成员函数,如果没
有 const 修饰的话可不可以呢?回答是可以!但是这样做的代价是:const 对象将不
能再调用这两个非 const 成员函数了。如
const string& get_name(); // 这两个函数都应该设成 const 型
int get_score();
void output_student( const Student& student )
{
get_score() 是非 const 成员函数,这一句和下一句调用是错误的
}
由 于参数 student 表示的是一个对 const Student 型对象的引用,所以 student 不
能调用非 const 成员函数如 set_student()。如果 get_name() 和 get_score()
成 员 函 数 也 变 成 非 const 型 , 那 么 上 面 的 student.get_name() 和
student.get_score() 的使用就是非法的,这样就会给我们处理问题造成困难。
因此,我们没有理由反对使用 const,该加 const 时就应该加上 const,这样使成员
函数除了非 const 的对象之外,const 对象也能够调用它。
c/C++ 通用 Makefile
本文提供了一个用于对 C/C++ 程序进行编译和连接以产生可执行程序的通用
Makefile。
在使用 Makefile 之前,只需对它进行一些简单的设置即可;而且一经设置,即使以
后对源程序文件有所增减一般也不再需要改动 Makefile。因此,即便是一个没有学习
过 Makefile 书写规则的人,也可以为自己的 C/C++ 程序快速建立一个可工作的
Makefile。
这个 Makefile 可以在 GNU Make 和 GCC 编译器下正常工作。但是不能保证对于
其它版本的 Make 和编译器也能正常工作。
如果你发现了本文中的错误,或者对本文有什么感想或建议,可通过 whyglinux AT
hotmail DOT com 邮箱和作者联系。
此 Makefile 的使用方法如下:
1. 程序目录的组织
尽量将自己的源程序集中在一个目录中,并且把 Makefile 和源程序放在一起,这样用
起来比较方便。当然,也可以将源程序分类存放在不同的目录中。
在程序目录中创建一个名为 Makefile 的文本文件,将后面列出的 Makefile 的内容复
制到这个文件中。(注意:在复制的过程中,Makfile 中各命令前面的 Tab 字符有可
能被转换成若干个空格。这种情况下需要把 Makefile 命令前面的这些空格替换为一个
Tab。)
将当前工作目录切换到 Makefile 所在的目录。目前,这个 Makefile 只支持在当前目
录中的调用,不支持当前目录和 Makefile 所在的路径不是同一目录的情况。
2. 指定可执行文件
程序编译和连接成功后产生的可执行文件在 Makefile 中的 PROGRAM 变量
中设定。这一项不能为空。为自己程序的可执行文件起一个有意义的名子吧。
3.指定源程序
要编译的源程序由其所在的路径和文件的扩展名两项来确定。由于头文件是通过包含
来使用的,所以在这里说的源程序不应包含头文件。
程序所在的路径在 SRCDIRS 中设定。如果源程序分布在不同的目录中,那么需要
在 SRCDIRS 中一一指定,并且路径名之间用空格分隔。
4.Makefile 目标(Targets)
下面是关于这个 Makefile 提供的目标以及它所完成的功能:
omake
编译和连接程序。相当于 make all。
omake objs
仅仅编译程序产生 .o 目标文件,不进行连接(一般很少单独使用)。
omake clean
删除编译产生的目标文件和依赖文件。
omake cleanall
删除目标文件、依赖文件以及可执行文件。
omake rebuild
重新编译和连接程序。相当于 make clean && make all。
下面提供两个例子来具体说明上面 Makefile 的用法。
例一 Hello World 程序
这个程序的功能是输出 Hello, world! 这样一行文字。由 hello.h、hello.c、main.cxx
三个文件组成。前两个文件是 C 程序,后一个是 C++ 程序,因此这是一个 C 和
C++ 混编程序。
代码:
/* File name: hello.h
* C header file
*/
#ifndef HELLO_H
#define HELLO_H
#ifdef __cplusplus
extern "C" {
#endif
void print_hello();
#ifdef __cplusplus
}
#endif
#endif
代码:
/* File name: hello.c
* C source file.
*/
#include "hello.h"
#include
void print_hello()
{
puts( "Hello, world!" );
}
代码:
/* File name: main.cxx
* C++ source file.
*/
#include "hello.h"
int main()
{
print_hello();
return 0;
}
建立一个新的目录,然后把这三个文件拷贝到目录中,也把 Makefile 文件拷贝到目
录中。之后,对 Makefile 的相关项目进行如下设置:
代码:
PROGRAM := hello
SRCDIRS := .
# 设置运行程序名
# 源程序位于当前目录下
SRCEXTS := .c .cxx
CFLAGS
:= -g
CXXFLAGS := -g
息
# 源程序文件有 .c 和 .cxx 两种类型
# 为 C 目标程序包含 GDB 可用的调试信息
# 为 C++ 目标程序包含 GDB 可用的调试信
由于这个简单的程序只使用了 C 标准库的函数(puts),所以对于 CFLAGS 和
CXXFLAGS 没有过多的要求,LDFLAGS 和 CPPFLAGS 选项也无需设置。
经过上面的设置之后,执行 make 命令就可以编译程序了。如果没有错误出现的
话,./hello 就可以运行程序了。
如果修改了源程序的话,可以看到只有和修改有关的源文件被编译。也可以再为程序
添加新的源文件,只要它们的扩展名是已经在 Makefile 中设置过的,那么就没有必
要修改 Makefile。
C/C++程序员应聘试题剖析
1.引言
本文的写作目的并不在于提供 C/C++程序员求职面试指导,而旨在从技术上分析
面试题的内涵。文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意
见。
许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试
者写一个最简单的 strcpy 函数都可看出面试者在技术上究竟达到了怎样的程度,我们
能真正写好一个 strcpy 函数吗?我们都觉得自己能,可是我们写出的 strcpy 很可能
只能拿到 10 分中的 2 分。读者可从本文看到 strcpy 函数从 2 分到 10 分解答的例子,
看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏捷的思维能力。
分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面
试题的深入剖析则可进一步增强自身的内功。
2.找错题
试题 1:
void test1()
{
char string[10];
char* str1 = "0123456789";
strcpy( string, str1 );
}
}
试题 2:
void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<10; i++)
{
str1[i] = 'a';
}
strcpy( string, str1 );