4.考察位运算
int main(int argc, char * argv[]) {
char ch = 'A';
int i = 65;
unsigned int f = 33554433;
*(int *)&f >>= 24;
*(int *)&f = *(int *)&f + '?';
printf("ch = %c i = %c f = %c\n", ch, i, *(int *)&f);
return 0;
}
*(int *)&f >>= 24;这一行将f由无符号整数强制转换为整数,在向右位移24,转换成2
*(int *)&f = *(int *)&f + '?';?在ascii中为63,所以得出的结果都是A
5.对指针和数组的理解
int main(int argc, char *argv[]) {
int a[2][2];
printf("&a = %p\t&a[0] = %p\t&a[0][0] = %p\n", &a, &a[0],
&a[0][0]);
printf("&a+1 = %p\t&a[0]+1 = %p\t&a[0][0]+1= %p\n", &a+1,
&a[0]+1, &a[0][0]+1);
return 0;
}
&a[0][0]地址为0x7fffffffe2a0;因为a中元素都是int类型,所以占四个字节。
&a[0][0]+1=&a[0][1];地址为0x7fffffffe2a4。
&a+1 ,地址为0x7fffffffe2b0 ,取a首元素的地址再加上16个字节。
&a[0]+1 = &a[1][0] ,地址为0x7fffffffe2a8
6.函数指针和指针函数
nt* get_array() {
int array[1121];
for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
array[i] = i;
}
}
return array;
int main(int argc, char *argv[]) {
int *p = get_array();
}
指针函数,简单的来说,就是一个返回指针的函数,其本质是一个函数,而该函数的返回值是一个指针。
int *fun(int x,int y);
函数指针,其本质是一个指针变量,该指针指向这个函数。总结来说,函数指针就是指向函数的指针。
int (*fun)(int x,int y);
在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能使用了,我们将这样的变量称为局部变量。
在调用get_array后会清空array的值,所以返回的是一个NULL,因此无法输出。
7.
int main(int argc, char *argv[]) {
char str[] = "XiyouLinuxGroup";
char *p = str;
char x[] = "XiyouLinuxGroup\t\106F\bamily";
printf("%zu %zu %zu %zu\n", sizeof(str), sizeof(p),
sizeof(x), strlen(x));
return 0;
}
其他的没什么看的,看看第2个。
sizeof(p)=8;sizeof(*p)=1.
对于任何指针变量p
,变量p
本身就是指针,它的大小就是指针的大小。*p
是p
指的是什么,大小是指的是什么的大小*p
。
因此,当sizeof(p)
报告,8您知道系统上的指针是8
字节,并且您可能在 64 位系统上。
如果sizeof(*p)
报告,4
那么您知道int
(p
在您的情况下指向的是什么)的大小是4
字节,这在 32 位和 64 位系统上都是正常的。
执行sizeof(int*)
会得到相同的结果sizeof(int)
。
哦还有最后一点:要打印sizeof
(类型为size_t
)的结果,那么您应该真正使用"z"
前缀和无符号类型说明符(因为size_t
是无符号的)。例如"%zu"
。不这样做在技术上是未定义的行为。
11.
puts((char*)(int const[]){
0X6F796958,0X6E694C75,0X72477875,
0X3270756F,0X313230,0X00000A
});
将十六进制转换成ASCII值,我们的 PC 机上使用的是 X86 结构的 CPU,它是小端模式;51 单片机是大端模式;很多 ARM、DSP 也是小端模式(部分 ARM 处理器还可以由硬件来选择是大端模式还是小端模式)。
6F796958,6F为高位,数据的高位放在内存的高地址上
内存地址 | 0x4000 | 0x4001 | 0x4002 | 0x4003 |
存放内容 | 0x58 | 0x69 | 0x79 | 0x6F |