1. 指针参数
void f(char *p)
{
p=(char *)malloc(10);
}
int main()
{
char *p=NULL;
f(p);
free(p);
return 0;
}
free(NULL)是可以的,只是指针变量做函数参数仍然是单向的值传递,p指针仍然是0,所以这里内存泄露了。
2.字符数组
char s1[24]="how are u";
char s2[24]="how are you";
int i,len = strlen(s2);
for (i=0;i<len;i++)
s1[i]=s2[i];
printf("s1=%s s2=%s/n",s1,s2);
这里s1和s2都能正常显示,因为s1后面全是自动补0.
3.void指针转换
class A
{
public:
A():a(2),p((void *)5)
{
printf("a=%d p=%d/n",a,p);
}
int a;
void *p;
};
int main()
{
A b;
}
这里p一定要用(void *)强制转换,但p的值是5,引用它会造成系统受影响。
4.堆内存,数据段,代码段
5.单链表反转
struct tagT
{
int data;
struct tagT *next;
};
typedef struct tagT T;
T *revert(T *head)
{
T *p=head, *pnext=NULL, *newHead=NULL;
while(p!=NULL)
{
pnext=p->next;
p->next=newHead;
newHead=p;
p=pnext;
}
return newHead;
}
T *insert(T *head, int data)
{
T *newNode = (T *)malloc(sizeof(T));
memset(newNode,0,sizeof(T));
newNode->data = data;
newNode->next = NULL;
T *p=head;
if ( NULL == p )
{
/* no one node */
return newNode;
}
else
{
/* point to end */
while ( p->next!=NULL )
{
p=p->next;
}
/* insert */
p->next = newNode;
return head;
}
}
void print(T *head)
{
T *p=head;
while (p!=NULL)
{
printf("%2d ", p->data);
p=p->next;
}
printf("/n");
}
int main()
{
T *head = NULL;
head = insert(head,1);
head = insert(head,2);
head = insert(head,3);
print(head);
head = revert(head);
print(head);
return 0;
}
6.两个大数相乘
char *multi(char *a, char *b)
{
int n=strlen(a), m=strlen(b);
int i=0,j=0;
int temp=0;
int *c=(int *)malloc(sizeof(int)*(n+m));
memset(c,0,(n+m)*4);
for ( i=0;i<n;i++)
for (j=0;j<m;j++)
c[i+j+1]+=(a[i]-'0')*(b[j]-'0');
for ( i=n+m-1;i>=0;i--)
{
if ( c[i]>=10 )
{
c[i-1]+=c[i]/10;
c[i]=c[i]%10;
}
}
char *p, *result=(char *)malloc(n+m+1);
memset(result,0, n+m+1 );
i=0;
while (c[i]==0)
i++;
p=result;
for (;i<n+m;i++,p++)
(*p)=(c[i]+'0');
return result;
}
7.用预处理指令
#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
8.写一个“标准”宏MIN
这个宏 输入两个参数并返回较小的一个。
#define MIN(A,B) ((A) <= (B) ?(A) : (B))
再看下面一个例子,输出是多少呢
#define MAX(A,B) ((A) >= (B)?(A):(B))
int b=3,a=4;
int *p=&a;
int least = MAX((*p)++,b);
printf("least=%d a=%d b=%d/n", least,a,b);
这个结果是,5,6,3,这就是宏定义的副作用,三目运算符可以看成2个表达式,前面一个已经
把a加1了,然后赋值给least。另外,这里*p++表达式,++的级别要高于*,所以要加括号。
9. 关键字volatile有什么含意 并给出三个不同的例子。
的变量是说这变量可能会被意想不到地改变,
下面是volatile变量的几个例 子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
应该为
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
10. 位操作
写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。
#define BIT3 (0x1<<3)
a |= BIT3;
a &= ~BIT3;
11. 指针地址
要求设置一绝对地址为0x67a9的整 型变量的值为0xaa66
把 一个整型数 转化成 一指针需要强制转换
short *ptr;
ptr = ( short *)0x67a9;
*ptr = 0xaa55;
12 . 类型提升
下面的代码输出是什么,为什么?
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6) puts("> 6") : puts("<= 6");
}
当表达式中存在有符号类型和无符号类型 时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6
13. 评价下面的代码片断 :
unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
/*1's complement of zero */
对于一个int型不是16位的处理器为说,上面的代码是不正确的。应编写如下:
unsigned int compzero = ~0;