简介
文章借鉴,以及本人的一些理解和发现。
C语言高级编程系列_hello_courage的博客-CSDN博客_c语言高级编程
#与##
C语言中"#"和"##"的用法_flist的博客-CSDN博客_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;
}
宏函数
可参照
求最小值的宏:#define min(x,y) x > y? y: x 中的陷阱,慎用_暴躁的野生猿的博客-CSDN博客
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;
}
数组所在内存地址
数组地址加一详解_奋斗的大庆的博客-CSDN博客_数组地址加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的博客-CSDN博客
把非 0 值转换为 1,0 值为 0