C语言高级特性

简介

        文章借鉴,以及本人的一些理解和发现。

C语言高级编程系列_hello_courage的博客-优快云博客_c语言高级编程

#与##

C语言中"#"和"##"的用法_flist的博客-优快云博客_c语言#的用法

#可以将符号转化为定义的字符串,##用于连接合并字符串

#define STR(s)     #s
#define CONS(a,b)  int(a##e##b)
int main()
{
   printf(STR(vck));           // 输出字符串"vck"
   printf("%d\n", CONS(2,3));  // 2e3 输出:2000
   return 0;
}
#include <stdio.h>
#define __stringfy(x) #x
int main(int argc, char* argv[]) 
{
    printf("%s",__stringfy(AA));
    return 0;
}

宏函数 

可参照

面试常问的16个C语言问题,你全会吗?

求最小值的宏:#define min(x,y) x > y? y: x 中的陷阱,慎用_暴躁的野生猿的博客-优快云博客

GUN编译器可以编译宏函数,VS不行

宏函数几乎可以实现模板编程,十分强大

#include <stdio.h>

#define  MIN(type, x, y)  ({\
    type _x = x;\
    type _y = y;\
    _x > _y ? _y : _x;\
})
int Min(int x, int y)
{
    int _x = x;
    int _y = y;
    return _x > _y ? _y : _x;
}
int main(void)
{
    int i = 2;
    int j = 6;
    printf("min = %d\r\n", Min(i++, j++));
    printf("min = %.2f\r\n", MIN(float, 3.14, 3.15));
}

在VS中需要多传入参数做返回

#include <stdio.h>

#define  MIN(type, x, y,c)  {\
    type _x = x;\
    type _y = y;\
    c = _x > _y ? _y : _x;\
}
int Min(int x, int y)
{
    int _x = x;
    int _y = y;
    return _x > _y ? _y : _x;
}
int main(void)
{
    int i = 2;
    int j = 6;
    float c;
    printf("min = %d\r\n", Min(i++, j++));
    MIN(float, 3.14, 3.15, c)
    printf("min = %.2f\r\n", c);
}

函数作为形参,并调用

#include <stdio.h>

void add(void) 
{
	printf("hello\n");
}
void add_2(void (*ptr)(void)) 
{
	ptr();
}
int main(void) 
{
	add_2( add);
	return 0;
}

数组所在内存地址

数组地址加一详解_奋斗的大庆的博客-优快云博客_数组地址加1

#include <stdio.h>

int main(void)
{
	int arr[2][3] = { {1,2,3},{4,5,6} };
	int i, j;
	printf("&arr:%d\t\n", &arr);
	printf("&arr+1:%d\t\n", &arr+1);	//把&arr+1这个地址打印
	printf("(int*)(&arr+1):%d\t\n", (int*)(&arr + 1));	//把&arr+1这个地址用一个指针指向
	for(i=0;i<2;i++)
		for(j=0;j<3;j++)
			printf("&arr[%d][%d]:%d\t\n",i,j,&arr[i][j]);
}

二重数组做形参,并通过指针操作

        二重数组相当于一个一维数组分了若干段,arr[0][0]指向第一行第一列

        代码分析:对于arr[2][3],

                                  0.以&arr,作为实参可以与(* a)[2][3]匹配

                                  1.以数组名arr,作为实参可以与a[][3]匹配,和(*a)[3]匹配,

                                                与&arr[0]等价

                                   2.以arr[0],作为实参可以与(*a)匹配,

                                                与&arr[0][0]等价

         结论:二维数组的地址等价于一个二维数组指针(*a)[2][3],&arr为其值(首地址)

                    二维数组等价于一个一维数组指针(*a)[3]&arr[0](首地址)为其值,等价于arr

                    二维数组等价于一个指针(*a)&arr[0][0](首地址)为它们的值,等价于arr[0]

                    二维数组为2x3的数值组合,&arr[0][0]~&arr[1][3]为它们的地址

#include<stdio.h>
#include <corecrt_malloc.h>

void print(int a[][3])
{
    int i, j;
    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d ", *a[i] + j);
        }
        printf("\n");
    }
    printf("\n");
}

void print_2(int (*p))
{
    int i, j;
    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 3; j++)
            printf("%d ", *(p + i * 3 + j));
        printf("\n");
    }
    printf("\n");
}
void print_3(int (*a)[3])
{
    int i, j;
    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d ", *a[i] + j);
        }
        printf("\n");
    }
    printf("\n");
}
void print_4(int(*a)[2][3])
{
    int  j;

     for (j = 0; j < 6; j++)
     {
        printf("%d ", *(*a[0]+j));
     }
        printf("\n");
    
}
void main(void)
{
    int i, j, arr[2][3] = {
      {1,2,3},
      {4,5,6}
    };
    print(arr);
    print_2(arr[0]);
    print_2(&arr[0][0]);
    print_3(arr);
    print_3(&arr[0]);
    print_4(&arr);
    printf("the a is %p\n", arr);
    printf("the a is %p\n", &arr);
}

三维指针及三重数组

#include <stdio.h>


void array_print(int a[][2][3]) //三维数组
{
    int i, j, k;
    for (i = 0; i < 2; i++) //相当于有两个一维指针
    {
        for (j = 0; j < 2; j++)
        {
            for (k = 0; k < 3; k++)
                //printf("%d", a[i][j][k]); //相当于有12个数字
                printf("%d", (*(a+i))[j][k]);
            printf("\n");
        }
        printf("\n");
    }
}

void array_print1(int* a[][3])  //一重二维数组指针
{
    int i, j;
    for (i = 0; i < 4; i++) //相当于有4个一维指针
    {
        for (j = 0; j < 3 ; j++)
            printf("%d", (a[i][j]));
        printf("\n");
    }
       
}
void array_print2(int** a[])    //二重一维数组指针
{
    int i;
    for(i=0;i<12;i++)   //12个一维指针指向12个数据
    printf("%d", a[i]); 
    printf("\n");
}
void array_print3(int*** a)     //三重指针
{
    int i, j;
    for (i = 0; i < 12; i++)    //相当于一个三重指针,一个指针
       // printf("%d", *(a + i));   //等价于 printf("%d", &**(a+i)); 
        printf("%d", a[i]);
}

int main(void)
{
    int a[2][2][3] = 
        { 
            {
                {1,2,3},
                {4,5,6}
            },
            {
                {7,8,9},
                {10,11,12}
            }
        };
    //int* ptr = (int*)(&a + 1);
    //printf("%d,%d",*(int *)(a+1),*(ptr-4));
    array_print(a);
    array_print1(a);
    array_print2(a);
    array_print3(a);
}

结构体数组及其指针

        3行3列指针,每一个行指针对应一个结构体,每一行中的每一列对应结构体中的一个成员

#include<stdio.h>
 
typedef struct test
{
    int a;
    int b;
    int c;
} TEST;
 
TEST arr[]={         //3行3列指针,每一个行指针对应一个结构体,每一行中的每一列对应结构体中的一个成员
    {1,2,3},
    {4,5,6},
    {7,8,9}
};
 
void main(void)
{
    TEST *tmp;
    tmp = arr;
 
    printf("tmp: %d, %d, %d,%d, %d, %d,%d, %d, %d\n", tmp[0].a, tmp[0].b, tmp[0].c, tmp[1].a, tmp[1].b, tmp[1].c, tmp[2].a, tmp[2].b, tmp[2].c);
    printf("arr: %d, %d, %d,%d, %d, %d,%d, %d, %d\n", arr[0].a, arr[0].b, arr[0].c, arr[1].a, arr[1].b, arr[1].c, arr[2].a, arr[2].b, arr[2].c);
}

 二重指针赋值

        #表示输出加0x,p1为i的地址,p2为p1的地址

#include<stdio.h>
int main(void)
{
    int i;
    int** p2 = NULL;
    int* p1 = NULL;

    p1 = &i;
    p2 = &p1;

    printf("p1 = %#x, p2 = %#x", p1, p2);   //#表示输出加0x.p1为i的地址,p2为p1的地址

    return 0;
}

结构体对其内部指针成员的引用

两种方法

#include <stdio.h>
struct Stu_Info
{
    const char* name; // 总线名字
};
int main()
{
    struct Stu_Info mystudent;
    mystudent.name = "bob";
    printf("%s\n",mystudent.name);

    struct Stu_Info mystudent1 = {
        .name = "bob",
    };
    printf("%s\n",mystudent1.name);
    return 0;
}

两个 !! : (383条消息) C语言中双感叹号(!!)的含义_!()c语言是啥_Qidi_Huang的博客-优快云博客 

把非 0 值转换为 1,0 值为 0  

#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1)) 的含义

1. C 语言中的指针和内存泄漏 ............................................................................................................. 5 2. C语言难点分析整理 .......................................................................................................................... 9 3. C语言难点 ........................................................................................................................................ 16 4. C/C++实现冒泡排序算法 ................................................................................................................. 29 5. C++中指针和引用的区别 ................................................................................................................. 31 6. const char*, char const*, char*const的区别 ..................................................................................... 32 7. C中可变参数函数实现 .................................................................................................................... 34 8. C程序内存中组成部分 .................................................................................................................... 37 9. C编程拾粹 ........................................................................................................................................ 38 10. C语言中实现数组的动态增长 .................................................................................................... 40 11. C语言中的位运算 ........................................................................................................................ 41 12. 浮点数的存储格式: .................................................................................................................... 45 13. 位域 ................................................................................................................................................ 52 14. C语言函数二维数组传递方法 .................................................................................................... 58 15. C语言复杂表达式的执行步骤 .................................................................................................... 60 16. C语言字符串函数大全 ................................................................................................................ 62 17. C语言宏定义技巧 ........................................................................................................................ 80 18. C语言实现动态数组 .................................................................................................................... 89 19. C语言笔试-运算符和表达式 ....................................................................................................... 93 20. C语言编程准则之稳定篇 ............................................................................................................ 96 21. C语言编程常见问题分析 ............................................................................................................ 97 22. C语言编程易犯毛病集合 .......................................................................................................... 101 23. C语言缺陷与陷阱(笔记) ............................................................................................................ 107 24. C语言防止缓冲区溢出方法 .......................................................................................................113 25. C语言高效编程秘籍 ...................................................................................................................115 26. C运算符优先级口诀 ...................................................................................................................119 27. do/while(0)的妙用 ....................................................................................................................... 120 28. exit()和return()的区别 ................................................................................................................ 125 29. exit子程序终止函数与return的差别 ........................................................................................ 126 30. extern与static存储空间矛盾 ..................................................................................................... 130 31. PC-Lint与C\C++代码质量 ........................................................................................................ 132 32. spirntf函数使用大全................................................................................................................... 142 33. 二叉树的数据结构 ...................................................................................................................... 150 34. 位运算应用口诀和实例 .............................................................................................................. 153 35. 内存对齐与ANSI C中struct内存布局 .................................................................................... 156 36. 冒泡和选择排序实现 .................................................................................................................. 162 37. 函数指针数组与返回数组指针的函数 ...................................................................................... 168 38. 右左法则- 复杂指针解析 ........................................................................................................... 170 39. 回车和换行的区别 ...................................................................................................................... 173 40. 堆和堆栈的区别 .......................................................................................................................... 175 41. 堆和堆栈的区别 .......................................................................................................................... 178 42. 如何写出专业的C头文件 ......................................................................................................... 181 43. 打造最快的Hash表 .................................................................................................................... 185 44. 指针与数组学习笔记 .................................................................................................................. 199 45. 数组不是指针 .............................................................................................................................. 201 46. 标准C中字符串分割的方法 ..................................................................................................... 205 47. 汉诺塔源码 .................................................................................................................................. 208 48. 洗牌算法 .......................................................................................................................................211 49. 深入理解C语言指针的奥秘 ..................................................................................................... 213 50. 游戏外挂的编写原理 .................................................................................................................. 229 51. 程序实例分析-为什么会陷入死循环 ......................................................................................... 232 52. 空指针究竟指向了内存的哪个地方 .......................................................................................... 234 53. 算术表达式的计算 ...................................................................................................................... 238 54. 结构体对齐的具体含义 .............................................................................................................. 242 55. 连连看AI算法 ............................................................................................................................ 246 56. 连连看寻路算法的思路 .............................................................................................................. 254 57. 重新认识:指向函数的指针 ......................................................................................................... 258 58. 链表的源码 .................................................................................................................................. 261 59. 高质量的子程序 .......................................................................................................................... 264 60. 高级C语言程序员测试必过的十六道最佳题目+答案详解.................................................... 266 61. C语言常见错误 .......................................................................................................................... 286 62. 超强的指针学习笔记 .................................................................................................................. 291 63. 程序员之路──关于代码风格 .................................................................................................. 306 64. 指针、结构体、联合体的安全规范 .......................................................................................... 309 65. C指针讲解 .................................................................................................................................. 314 66. 关于指向指针的指针 .................................................................................................................. 327 67. C/C++ 误区一:void main() ...................................................................................................... 331 68. C/C++ 误区二:fflush(stdin) ..................................................................................................... 334 69. C/C++ 误区三:强制转换 malloc() 的返回值 ........................................................................ 338 70. C/C++ 误区四:char c = getchar(); ............................................................................................ 339 71. C/C++ 误区五:检查 new 的返回值....................................................................................... 341 72. C 是 C++ 的子集吗? .............................................................................................................. 342 73. C和C++的区别是什么? .......................................................................................................... 345 74. 无条件循环 .................................................................................................................................. 346 75. 产生随机数的方法 ...................................................................................................................... 347 76. 顺序表及其操作 .......................................................................................................................... 348 77. 单链表的实现及其操作 .............................................................................................................. 349 78. 双向链表 ...................................................................................................................................... 353 79. 程序员数据结构笔记 .................................................................................................................. 357 80. Hashtable和HashMap的区别.................................................................................................... 364 81. hash 表学习笔记 ......................................................................................................................... 366 82. C程序设计常用算法源代码 ...................................................................................................... 368 83. C语言有头结点链表的经典实现 .............................................................................................. 375 84. C语言惠通面试题 ...................................................................................................................... 383 85. C语言常用宏定义 ...................................................................................................................... 402
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值