1、局部变量能否和全局变量重名?
答:局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内
2、如何引用一个已经定义过的全局变量?
答:可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
3、全局变量定义在可被多个.C文件包含的头文件中可不可以?为什么?
答:可以,但要加static
4、语句for( ;1 ;)有什么问题?它是什么意思?
答:死循环,同while(1),这种写法并不规范,可读性差,一般不用
5、请写出下列代码的输出内容
#include
main()
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf("b,c,d:%d,%d,%d",b,c,d);
return 0;
}
答:10,12,120(注意它)
6.static函数与普通函数有什么区别?
只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。
8.static全局变量与普通的全局变量有什么区别?
全局变量(外部变量)的说明之前再冠以static
就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。
这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
9.程序的局部变量存在于(栈)中,全局变量存在于(静态区)中,动态申请数据存在于(堆)中。
10.设有以下说明和定义:
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));的执行结果是:52(请高手分析一下)size(DATA)=最长的变量字节数=4*5=20
所以sizeof(struct
date)=4+20+8=32 sizeof(max)=20 最终=52
11.队列和栈有什么区别?
队列先进先出,栈后进先出
12.请找出下面代码中的所以错误
说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”
main(){
char*src="hello,world";
char* dest=NULL;
int len=strlen(src);
dest=(char*)malloc(len);//!1 少分配了一字节. strlen计数不包括
char* d = dest;
char* s = src[len];//!2 两个错误. 应该为 &src[ len-1
]
while( len-- != 0 )
d++=s--;//!3 *d++ = *s--;
//!4 尾部要 ,应加上 *d = 0;
printf("%s",dest);
return 0;
}
修正后的答案:
int main(){
char* src = "hello,world";
int len = strlen(src);
char* dest = (char*)malloc(len+1);.
char* d = dest;
char* s = &src[len-1];
while( len-- != 0 )
*d++=*s--;
*d = 0;
printf("%s",dest);
return 0;
}
13.写出下列代码的输出内容
#include
int inc(int a)
{
return(++a);
}
int multi(int*a,int*b,int*c)
{
return(*c=*a**b);
}
typedef int(FUNC1)(int in);
typedef int(FUNC2) (int*,int*,int*);
void show(FUNC2 fun,int arg1, int*arg2)
{
INCp=&inc;
int temp =p(arg1);
fun(&temp,&arg1, arg2);
printf("%dn",*arg2);
}
main()
{
int a;
show(multi,10,&a);
return 0;
}
翻译一下
#include
using namespace std;
// 返回a + 1
int inc(int a){
return a+1;
}
// out = a*b
int multi(int& a, int& b,
int& out){
return out = a*b;
}
// 定义两种函数,FUNC1对应inc, FUNC2对应 multi
typedef int(FUNC1) (int in);
typedef int(FUNC2)
(int&,int&,int&);
// 诡异的函数,这是模糊C大赛么...
void show( FUNC2* func, int num, int& out
){
FUNC1* pInc = inc;//原文这句写错了...orz... INC根本没定义
int numAdd1 = pInc( num );
// 等价于 numAdd1 = inc( num );
// 结果 num仍然是10, numAdd1 = 11
// 调用func函数,可以看到, main中传给func的是 multi.
// 所以调用的是 multi( 11, 10, out ), out = 110
func( numAdd1, num, out );
cout
int main(){
int a;
show(multi,10, a);
return 0;
}
14.将任意正数N分解成多个互不相同的正整数的和,并打印所有可能的组合方式。例如N=6,组合方式有1+5,2+4,1+2+3。
#include "stdafx.h"
#include "stdlib.h"
static int n;
int *a;
static int total =0 ;
void output(int s){
int i=1;
printf("%d = %d",n,a[i]);
for(i=2; i<=s; i++){
printf("+%d",a[i]);
}
printf("n");
}
int filter(int s){
int i,j;
if(s==1)return -1;
for(i=s;i>0;i--)
for(j=1;j if(a[i]==a[j])
return -1;
}
return 0;
}
void dfs(int d,int low,int rest){
//printf("d = %d ,low = %d ; rest =%dn",d,low,rest);
int i;
if(rest == 0){
if(filter(d-1)==0){
total ++;
output(d-1);
}
}
if(low>rest) {
//printf("1111111111111n");
return ;
}
for(i=low;i<=rest;i++){
a[d]=i;
dfs(d+1,i,rest-i);
}
}
int main(int argc, char* argv[])
{
int num;
printf("input:");
scanf("%d",&num);
n=num ;
a =(int *)malloc(sizeof(int)*(n+1));
dfs(1,1,n);
printf("total = %dn",total);
free(a);
return 0;
}
15.在linux下防止某个程序被运行两次的方法
通过文件锁来实现,在程序运行的一开始,检查某文件是否存在,如果存在则说明改程序已经在运行了,如果不存在则利
用open语句创建该文件,程序退出时关闭并删除此文件。
具体代码:
static char file_lock[sizeof(ctl_addr.sun_path)] =
/var/run/file.pid;
static bool file_lock_created = FALSE;
static int
create_lock(void)
{
int fd = open(file_lock, O_WRONLY | O_CREAT | O_EXCL |
O_TRUNC,
S_IRUSR | S_IRGRP | S_IROTH);
if (fd < 0)
{
if (errno == EEXIST)
{
fprintf(stderr, "file: lock file "%s" already existsn",
file_lock);
exit_file(10);
}
else
{
fprintf(stderr, "file: unable to create lock file "%s" (%d
%s)n"
, file_lock, errno, strerror(errno));
exit_file(1);
}
}
file_lock_created = TRUE;
return fd;
}
static bool
fill_lock(int lockfd)
{
char buf[30];
pid_t pid;
int len;
pid = getpid();
len = snprintf(buf, sizeof(buf), "%un", (unsigned int)
pid);
bool ok = len > 0
&& write(lockfd, buf, len) ==
len;
close(lockfd);
return ok;
}
static void
delete_lock(void)
{
if (file_lock_created)
{
//delete_ctl_socket();
unlink(file_lock);
}
}
17.位结构面试题
#include
void main()
{
union
{
struct
{
unsigned short s1:3;
unsigned short s2:3;
unsigned short s3:3;
}x;
char c;
}
}v;
v.c=100;
printf("%dn",v.x.s3);
}
A:4 B:0 C:3 D:6
答案是A
但我在TURBO C中运行答案是1
请问 是因为TURBO C 版本在原因而运行结果不一样吗?
我用在TURBO C V2.0版本
能解释一下为甚么是4或1?
而v.x.s1和v.x.s2的 值 在TURBO C V2.0版本运行的结果是4?
其中unsigned short s1:3; 中的“:”又是什么意思?
解答:
位结构是一种特殊的结构, 在需按位访问一个字节或字的多个位时, 位结构
比按位运算符更加方便。
位结构定义的一般形式为:
struct位结构名{
数据类型 变量名: 整型常数;
数据类型 变量名: 整型常数;
} 位结构变量;
其中: 数据类型必须是int(unsigned或signed)。 整型常数必须是非负的整数, 范围是0~15, 表示二进制位的个数,
即表示有多少位。
变量名是选择项, 可以不命名, 这样规定是为了排列需要。
例如: 下面定义了一个位结构。
struct{
unsigned incon: 8;
unsigned txcolor: 4;
unsigned bgcolor: 3;
unsigned blink: 1;
}ch;
位结构成员的访问与结构成员的访问相同。
例如: 访问上例位结构中的bgcolor成员可写成:
ch.bgcolor
注意:
1. 位结构中的成员可以定义为unsigned, 也可定义为signed, 但当成员长度为1时,
会被认为是unsigned类型。因为单个位不
可能具有符号。
2. 位结构中的成员不能使用数组和指针, 但位结构变量可以是数组和指针, 如果是指针, 其成员访问方式同结构指针。
3. 位结构总长度(位数), 是各个位成员定义的位数之和, 可以超过两个字节。
4. 位结构成员可以与其它结构成员一起使用。
例如:
struct info{
char name[8];
int age;
struct addr address;
float pay;
unsigned state: 1;
unsigned pay: 1;
}workers;''
上例的结构定义了关于一个工从的信息。其中有两个位结构成员, 每个位结构成员只有一位, 因此只占一个字节但保存了两个
信息, 该字节中第一位表示工人的状态, 第二位表示工资是否已发放。由此可见使用位结构可以节省存贮空间。
结构struct x,有三个成员s1,s2,s3每一个成员占3 bit,
结构与char c union ;
char 一般机器占一个字节(8 bit ,100 二进制值为:01100100,所以s1后三bit(6,7,8 bit)
:100
s2为中间三位(3,4,5 bit)为100 s3为01,所以printf("%dn",v.x.s3)是1,其它是4
现在大多数系统都是将低字位放在前面,而结构体中位域的申明一般是先声明高位。
100 的二进制是 001 100 100
低位在前 高位在后
001----s3
100----s2
100----s1
所以结果应该是 1
如果先申明的在低位则:
001----s1
100----s2
100----s3
结果是 4
其中unsigned short s1:3; 中的“:”又是什么意思?
指定位段, 3代表预定s1占3bit.
为什么是4?
struct
{
unsigned short s1:3; //一个字节. 虽然预定为3bit,但系统的存储空间为至少一字节.
unsigned short s2:3; //一个字节
unsigned short s3:3; //一个字节
}x;
这样在联合union中最大的成员为三个字节,而最终结果为了内存对齐(对齐为4的倍数).取为4.
其它问题楼上已经给出了答案.
18.如何定位全局数组的写越界
一个被大量引用的全局数组int a[100],被写越界了,这样的情况如何定位?
最简单的方法是,将数组a[100]改为a[101],然后对访问a[100]的地方设置断点进行调试。因为a[100]应该是没有人访问
的,如果访问就是越界访问,直接可以定位到该位置。
另外:将函数定义成static类型可以防止该文件意外的其他文件中的函数调用此函数。
19.内存泄漏
struct chunk_t
{
u_char *ptr;
size_t len;
};
int key_switch(const struct RSA_public_key *k, R_RSA_PUBLIC_KEY
*publickey)
{
chunk_t exponent,modulus;
publickey->bits
=(k->k)*BITS_PER_BYTE;
modulus =
mpz_to_n(&(k->n),k->k);
exponent =
mpz_to_n(&(k->e),k->k);
memcpy(publickey->modulus+128,modulus.ptr,modulus.len);
memcpy(publickey->exponent+128,exponent.ptr,exponent.len);
…… ……
return 0;
}
象上面这样的函数,其中在调用mpz_to_n的时候进行了malloc内存分配,别以为chunk_t
exponent,modulus;是局部变量
就没问题,如果函数退出前不释放mpz_to_n申请的空间,就会存在内存泄漏问题。
应该在…… ……处加上代码:
freeanychunk(modulus);
freeanychunk(exponent);
指针释放的问题早就知道了,但是实际应用中还是会因为没注意到而忘了。由于分配内存使用的是对malloc封装的函数
alloc_bytes(),所以使用相关的内存泄漏调试工具会定位到alloc_bytes()函数里,根本不能定位到具体泄漏的地点。
所以说对malloc/free进行二次封装有它的好处,同时也会带来坏处