程序猿之---C语言细节9

主要内容:宏定义、max(a,b)宏定义细节、大小端判断、(int&)a什么意思

#if 1
#include <stdio.h>

// 注意空格
#define F (x) ((x) - 1)   // F代表后面
#define F(x) ((x) - 1)    // F(x)代表后面

#define T1 struct type*
T1 a,b;  // 使用上面在定义多个变量时达不到目的,被解析为struct type* a,b;  a为指向结构体的指针,而b被定义为一个结构体
 // 经典的笔试题宏定义求最大值
//#define max(a,b) a>b?a:b          //这个很容易错,下面的比较不容易错,但是也会有错的时候
#define max(a,b) ((a)>(b)?(a):(b))     // 写成这样得不到满分,仍然可能会出现问题,解释如下
                                       // 同时这个宏定义也没有考虑传入不同类型的参数情况,

 /*
  *   如果一个操作数在两处被用到,就会被求值两次;
  *   表达式max(a,b)中如果带有副作用,在比较大小时会计算一次,在后面计算值时也会计算一次
  *   错误例子如下 :
  */
int main(int argc, char** argv)
{
    int x[3] = {2,3,1};
    int biggest = x[0];
    int i = 1;

    while(i < 3)
    {
    	biggest = max(biggest, x[i++]);  // 被拆解为biggest > x[i++]?biggest:x[i++],(biggest=2)<(x[1]=3)
										 //  关键点在于i在比较大小时有副作用,i++在后时i已经加1,biggest=x[2]
    }                                    // 解决方法是确定参数中没有副作用,或则直接编写max函数
    printf("biggest is %d\n",biggest);

//    一种考虑传入不同变量类型的max宏定义
//比较正确的答案应为:
#define MAX(a,b) ({            const typeof(a) _a = a;            const typeof(b) _b = b;            (void)(&_a == &_b); \
           _a > _b ? _a : _b;})
	return 0;
}

// 下面是测试大小端的方法 ,已经使用#if #elif  需要自己打开相应开关
// 补充一个 (int&)a是什么意思 ?(int&)a就是*(int*)(&a)
#elif 1 

#include<stdio.h>

int main()
{
    int x = 1;
    char *p = (char *)&x;

    if(*p)
    {
        printf("little\n");
    }
    else
    {
        printf("large\n");
    }
    return 0;
}

#else 

#include <stdio.h>

int main()
{
    short int x;
    char x1,x2;
    x = 0x1122;
    x1 = ((char *)&x)[0];    //低地址
    x2 = ((char *)&x)[1];    //高地址
    printf("x1=%x\n",x1);
    printf("x2=%x\n",x2);
    return 0;
}

#endif 

输出:

宏定义和大小端

时间: 2024-08-26 21:02:39

程序猿之---C语言细节9的相关文章

程序猿之---C语言细节24(段错误、类型提升、sizeof &#39;A&#39;)

主要内容:段错误.类型提升.sizeof  'A' #include <stdio.h> int main() { union test{ char a[10]; int b; }u; int *p = (int *)&(u.a[1]); // 没有引起总线错误 *p = 17; printf("%d\n",*p); #if 0 int *q = 0; // 引起段错误,在linux中运行可看到段错误,在windows下运行时直接出错 *q = 1; #endif

程序猿之--C语言细节15(预处理命令细节#error、运算符#和##、__FILE__、__LINE__)

主要内容:预处理命令细节#error.运算符#和##.__FILE__.__LINE__ #include <stdio.h> /* 包含这个头文件,并不是将其所有函数都链接进程序*/ /* ##运算符 */ #define MK_ID(n) i##n /* 表示将两个记号连接 */ int MK_ID(1), MK_ID(2),MK_ID(3); /* 预处理后变成int i1,i2,i3;*/ /* 定义多个type##_max函数,函数返回类型和参数类型用define决定 * 如GENE

程序猿之---C语言细节27(函数无参数时细节、函数默认返回int型证明、return默认还回值、void指针++操作)

主要内容:函数无参数时细节.函数默认返回int型证明.return默认还回值.void指针++操作 一.函数无参数时细节 函数无参数时应该加上void 在c语言中一个函数 void f(); 在使用时传递参数f(2);没有报错,而在c++中则会报错 最好加上void来明确函数是无参数的 二.函数默认返回类型为int型 见下面程序 三.return默认返回1 细节:return不可返回执行栈内存中的指针,因为该内存在函数体结束时自动销毁 四.void 指针++操作 void *p; p++; //

程序猿之---C语言细节26(C语言中布尔类型、continue细节、sizeof举例、strlen举例)

主要内容:C语言中布尔类型.continue细节.sizeof举例.strlen举例 一.布尔类型 可能很多人不知道现在C语言已经有了布尔类型:从C99标准开始,类型名字为"_Bool" 在C99标准之前我们常常自己模仿定义布尔类型,常见有以下几种方式: 1.方式一 #define TURE 1 #define FALSE 0 2.方式二 typedef enum {false, true} bool; 3.方式三 typedef int bool 闲int浪费内存,对内存敏感的程序使

程序猿之---C语言细节28(const变量初始化、数组大小用const变量细节、const变量与#define宏、volatile修饰)

主要内容:const变量初始化.数组大小用const变量细节.const变量与#define宏.volatile修饰 一.const变量初始化时必须赋值 二.const变量在C++中可以做数组大小元素.在C中不行,因为它是变量 三.const和#define区别:内存分配 四.volatile修饰一些变量:易被操纵系统.硬件.多线程修改的变量 #include <stdio.h> int main() { /* 测试1 */ const int b; // 不初始化会报错 // b = 2;

程序猿之---C语言细节(指针和数组细节,&quot;//&quot;的可移植性说明)

主要内容:指针和数组细节,"//"的可移植性说明 #include <stdio.h> int main(int argc, char **argv) { int a[10]={1,2,3,4,5,6,7,8,9,0},*p; #if 0 /* 按移植性来说,在<c语言程序设计--现代方法>指出要用当前注释方法,而不是// 因为一些编译可能不支持 */ // 错误举例 while(*a != 0) { a++; // a++ 相当于a = a+1,不能改变a的值

程序猿之---C语言细节10(++操作很可能你会出错)

主要内容:++操作细节 #include <stdio.h> int main(int argc, char** argv) { int t1 = 2, t2 = 0; //t2 = t1++ + t1++; // 在语句结束后才执行两个++,结果t2 = 4 t2 = t1++ > 0? t1++:t1; // 这里直接在?判断完之后执行了一次++操作,结果t2 = 3 printf("t2 = %d\n",t2); return 0; } 结果:

程序猿之---C语言细节31(#define和#undef宏细节)

主要内容:#define和#undef宏细节 一.#define和#undef宏细节 宏生命周期从#define开始到#undef结束 # include <stdio.h> #define BSC // #define BMC /* #define EMC */ #define ewaece #define sizeof //下面这个编译错误,上面两个可以编译通过 //#define int int main() { <span><span> </span>

程序猿之---C语言细节5

主要内容:字符串内存分配.合并两个字符串 #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { /* * 字符串操作:内存分配 * 字符串s和t,希望将这两个字符串连接成单个字符串r */ char* s = "abc"; char* t = "def"; // 方法一: 缺点:1.不能确定r指向何处: // 2.同时不知道r所指向的内存空间是否有可

程序猿之---C语言细节29(#define宏大小、空结构体大小、柔性数组不知道你见过没)

主要内容:#define宏大小.空结构体大小.柔性数组 一.#define宏大小 见例子 二.空结构体大小 根编译器有关 三.柔性数组 不常用,可看看 #include <stdio.h> #define N 4 #define STR "abcd" int main() { struct student { }stu; printf("N = %d\n", sizeof(N)); printf("num 5 memery = %d\n&quo