做错过的C语言题目- 微信“程序猿”推荐 -2014-03-12 20:39

看微信里“程序猿”推荐文章--“ 做错过的C语言题目”,很多不确定的,更有没见多的。 其他一些C语言易错题库: 语言的歧义C语言的谜题
第一个宏应用:

#include <stdio.h>  
#define STRCPY(a, b) strcpy(a ## _p, #b)  
int main()  
{  
    char var1_p[20];  
    char var2_p[30];  
    strcpy(var1_p, "aaaa";  
    strcpy(var2_p, "bbbb";  
    STRCPY(var1, var2);  
    STRCPY(var2, var1);  
    printf("var1 = %s/n", var1_p);  
    printf("var2 = %s/n", var2_p);  
    return 0;  
}  

宏中 #把宏参数变为一个字符串,用##把两个宏参数贴合在一起,均在预处理时就完成字符串的替换。所以STRCPY(var1, var2); 编译好后是strcpy(var1_p, "var2");

所以结果是
var1 = var2 
var2 = var1

第二个宏:
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%sn", h(f(1,2)));
printf("%sn", g(f(1,2)));
return 0;
}
宏定义替换的次序:如果该宏为带#号的宏定义,则直接替换字符串,无需再嵌套替换,如果该宏不是带#的宏,则先替换括号内部的宏定义,然后替换外部的。
结果:12和f(1,2)

第三个宏:定义一个宏,求一个结构体struct中某个变量相对于struct的偏移量
#define OFFSET(struc, member) ((unsigned int)&((struc *)0)->member)
(struc*)0 //表示将常量0强制转化为struc *型指针所指向的地址,
 
((struc*)0)- >e 表示在0地址处的结构体struc的成员e   
&(((struc*)0)- >e)//表示取结构体指针(struc*)0的成员e的地址, 因为该结构体的首地址为0,所以其实就是得到了成员e距离结构体首地址的偏移量.

指针题:
 定义一个指针如int *p; 要记住说p指向了一个int型存储空间, 指的是 p保存的是该存储空间的地址,*p的操作是指将取p保存地址的值;

#incude <stdio.h>
void main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
a表示第一个元素的地址,&a表示数组结构的地址。ptr指向的是整个a数组后的第一个存储空间,所以ptr-1表示的是a数组到最后一个元素的地址。
结果 2,5

假如我们的a的地址是:0Xbfe2e100, 而且是32位机,那么这个程序会输出什么
#include <stdio.h>
int main()
{
int a[5];
printf("%xn", a);
printf("%xn", a+1);
printf("%xn", &a);
printf("%xn", &a+1);
return 0;
}
结果:0Xbfe2e100,0Xbfe2e104,0Xbfe2e100,0Xbfe2e114  
 每一个字节对应一个地址,而不是每个比特对应一个地址


char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
答:0 0 1 1。
析:虽然都是常量,但是数组有空间,指针没空间。str1和str2都是单独开启一个空间存储“abc”串,但str5和str6保存的都是串“abc”的地址,所以 str5 == str6

不同类型的变量在一块运行的转化原则:有符号要向无符号的方向转化

编译器解析关键字是从左向右的,尽量包含更多的字符组成关键字


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));
答:32系统为52,64位系统64
32位和64位系统中基本数据字节长度(另一篇文章有)和存储对齐。 共用体的大小按最长变量算,结构的大小是各变量长的总和。 32位系统默认是4字节也就是32位对齐,不足则补齐,64位系统默认是8字节。
32位系统中,DATE的大小是按int k[5]的20字节,正好对齐,too的大小是4+20+8,所以总和是52;
64位系统中,DATE的大小同样按int k[5]的20字节,但还要8字节对齐,所以另外添4字节,too结构体中每个变量都要按8字节对齐,所以是8+24+8=40,总和64.

#include <stdio.h>
int main()
{
int i = 1;
sizeof(i++);
printf("%dn", i);
return 0;
}
答:1
分析:正因为 sizeof是编译期求值的,所以如果它跟着表达式,那么表达式是不会在运行时计算的,只是根本表达式的类型得到它占用的空间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值