1.数组指针和指针数组的区别
数组指针:int(*p)[n];
()优先级高,所以p首先是一个指针,指向一个整形的一维数组,这个一维数组的大小为n个int。
用法:让数组指针指向二维数组
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //让p指向a的首地址。
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]。
指针数组:int p[n];
[]的优先级高,p首先是一个数组,然后再与int结合为一个整形指针的数组,p数组中的每个元素都是int型的指针。
将指针数组指向二维数组
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
共同点:二者表示数组中i行j列的方式相同。
p[i][j]、(p[i]+j)、(p+i)[j]、((p+i)+j)
2.C语言在#define中使用参数
用宏参数创建字符串:#运算符
作用:#号作为一个预处理运算符,可以把记号转换成字符串。
例如:
#define PSQR(x) printf("the squre of " #x " is %d.\n", ((x)*(x)) )
int main(int argc, char *argv[])
{
int y = 5;
PSQR(y);
PSQR(2 + 4);
return 0;
}
输出为:
the square of y is 25.
the square of 2 + 4 is 36.
预处理器黏合剂:##运算符
作用:##运算符可以把两个记号组合成一个记号。
例如:
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main(int argc, char *argv[])
{
printf( "%s\n", h(f(1,2)) );
printf( "%s\n", g(f(1,2)) );
return 0;
}
输出为:
12 //h(f(1,2))先进行f(1,2),然后将12作为g的参数。
f(1,2) //g(f(1,2))将f(1,2)作为参数。
变参宏:…和__VA_ARGS__
作用:把宏参数中最后的参数写成省略号,用__VA_ARGS__来代表省略号表示什么。
例如:
#define PR(...) printf(__VA_ARGS__)
PR("HOWDAY");
PR("weight = %d, shipping = $%.2f\n", wt, sp);
输出为:
printf(“HOWDAY”);
printf("“weight = %d, shipping = $%.2f\n”, wt, sp");
记住,省略号只能代替最后的宏参数:
#define WRONG(x, …, y) #x #VA_ARGS #y //不能这么做
面试题
#define NAME(n) x##n //输出为xn
#define PRINTVAL(y, ...) printf("x"#y":"__VA_ARGS__)
int main(int argc, char *argv[])
{
int NAME(1);
short *NAME(2) = ( short *)&NAME(1);
char *NAME(3) = (char *)&NAME(1);
NAME(1) = 0;
*NAME(2) = -1; //NAME(2)在内存中为16个1
PRINTVAL(1, "%x\n", NAME(1)); // NAME(1)的值为65535,二进制为16个1
PRINTVAL(2, "%x\n", *NAME(2)); //NAME(2)的值为-1
PRINTVAL(3, "%x\n", *NAME(3)); //NAME(3)的值为-1
return 0;
}
输出为:
x1:ffff //%x会将输出的数据自动转化为unsigned int类型
x2:ffffffff //unsigned int下的-1为2^32-1
x3:ffffffff
int main(int argc, char *argv[])
{
int a[3][2] = { 2, 0, 1, 8 };
char *str = (char *)malloc(sizeof(char) * 20);
strcpy(str, "\0101\\xb2"); // \0oo后边跟有效的二位八进制,\010表示\b,\\表示一个\
printf("%zu\n", sizeof(a));
printf("%zu %d\n", sizeof(a[1][1] = 0), a[1][1]);//sizeof运算符的计算发生在编译时刻,这里并不能改变a[1][1]的值。
printf("%zu %zu\n", sizeof(str), strlen(str)); //指针的大小为8, str的长度为6。
return 0;
}
输出为:
24
4 8
8 6
下列结构体在内存中所占空间大小分别是多少?
struct node
{
int x; // x的偏移量为0
char y; //y的偏移量为4
double z; //z的偏移量为8,则结构体的大小为16.
};
struct node
{
int x; //x的偏移量为0
double y; //y的偏移量为8
char z; //z的偏移量为16, 为了满足结构体的大小为成员大小的整数倍,则结构体的大小为24.
};