嵌入式c学习八
练习
一、指针数组与数组指针
#include <stdio.h>
int main()
{
//c是一个指针数组,里面有4个元素每个元素都是指针
char *c[] = {"hello", "world", "homed", "gotogo"};
//cp是指针数组,有4个元素,每个元素都是指针,每个指针下存的地址里面对应的内容是指针==》字符串
char **cp[] = {c+3, c+2, c+1, c};
//cpp是指针变量,cpp存的是指针——>指针下存储的地址下对应的值还是指针——>指针所指向的值是指针——>指针指向字符常量
char ***cpp = cp; //cpp == &cp[0] == &(c+3) == &("gotogo")
//——》++cpp ==> &cp[0] + 1 == cp[1]
//——》*++cpp == *&cp[1] == cp[1] == &"homed"
//——》**++cpp == *&"homed" == "home" == &'h'
printf("**++cpp: %s\n\n", **++cpp); //homed ——》此时cpp == &cp[1]
//——》++cpp == &cp[2]
//——》*++cpp == *&cp[2] == cp[2] == &"world"
//——》--*++cpp == &"world" -1 == &"hello"
//——》*--*++cpp == *&"hello" == "hello" == &'h'
//——》*--*++cpp + 3 == &'h' + 3 == &'l'
printf("*--*++cpp+3: %s\n\n", *--*++cpp+3); //lo ——》此时cpp == &cp[2]
//——》cpp[-2] == *(cpp - 2) == *(&cp[2] - 2) == *&cp[0] == cp[0] == &"gotogo"
//——》*cpp[-2] == *&"gotogo" == "gotogo" == &'g'
//——》*cpp[-2] + 3 == &'g' + 3 == &'0'
printf("*cpp[-2] + 3: %s\n\n", *cpp[-2] + 3); //ogo ——》此时cpp == &cp[2]
//——》cpp[-1] == *(cpp - 1) ==> *(&cp[2] - 1) ==> *&cp[1] == cp[1] == &"homed"
//——》cpp[-1][-1] == &"homed"[-1] ==> *(&"homed" - 1) ==> *&"world" == "world" == &'w'
//——》cpp[-1][-1] + 1) == &'w' + 1 ==> &'0'
printf("cpp[-1][-1] + 1: %s\n\n", cpp[-1][-1] + 1); //orld
return 0;
}
二、二级指针
#include <stdio.h>
int main()
{
int a[5] = {2,4,6,8,10};
int *p = a; //p ==> &a[0];
//q是二级指针,其指向的内存空间(指针p的地址)里面的数据是一个地址,且该数据再次指向一个内存空间,里面的数据是int
int **q = &p; //q ==> &p
printf("*(p++): %d\n", *(p++)); //2: --》++在后,p先参与运算在自增1,运算结束后,p ==> &a[1]
printf("**q:%d\n", **q); //4
return 0;
}
三、二维数组的访问
#include <stdio.h>
int main()
{
int a[3][4] = {0};
a[1][1] = 0;
printf("a[1][1]:%d\n", a[1][1]);
*(a[1]+1) = 1;
printf("*(a[1]+1):%d\n", a[1][1]);
*(&a[1][1]) = 2;
printf("*(&a[1][1]):%d\n", a[1][1]);
return 0;
}
四、sizeof()函数
#include <stdio.h>
int main()
{
char str[] ="hello,world";
char *p = str;
int n =10;
printf("sizeof(str):%d\n", sizeof(str)); //12--> hello,world\0
printf("sizeof(p):%d\n", sizeof(p)); //4--> p是地址,32位系统地址为4个字节
printf("sizeof(10):%d\n", sizeof(10)); //4--> 整型4个字节
return 0;
}
五、大端小端存储
小端存储:低地址中存储低字节
大端存储:低地址中存储高字节
六、指针数组
#include <stdio.h>
int main()
{
//s是指针数组
char *s[] = {"one", "two", "three"};
char *p = s[1]; // p ==> "two" => &'t'
printf("%c\n%s\n", *(p+1), s[0]);
return 0;
}
七、位运算
#include <stdio.h>
int main()
{
int a = 0b1000;
printf("%d\n", a); //8
//设置a的第三位
a |= (1<<2);
printf("%d\n", a); //0b1100 == 12
//清除a的第三位
a &= ~(1<<2);
printf("%d\n", a); //0b1000 == 8
return 0;
}
八、if else语句
#include <stdio.h>
int main()
{
int a=1, b=2, x=0;
// --a == 0 ==> !--a ==>1,条件成立执行x--,x=-1
if(!(--a))x--;
//b == 2 ==> !b ==>0 ,条件不成立执行else语句,++x ==> x=0
if(!b)x=7;else ++x;
printf("x=%d\n", x);
}
九、头文件包含<>与“”的区别
#include <stdio.h>:编译器会在系统默认的包含路径中搜索头文件,通常用于包含系统提供的头文件
#include“stdio.h”:编译器首先在当前源文件所在目录中搜索头文件,找不到再到系统默认路径搜索,通常用于包含用户自定义的头文件
十、三维数组
#include <stdio.h>
int main()
{
int a[2][2][3] = {{{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}}};
//&a表示整个数组的地址,向后偏移以为即ptr指向下一个不存在的数组,已经越界
int *ptr = (int *)(&a + 1);
//a表示数组收元素地址&a[0],a+1=&a[1]-->(int*)-->&a[1][1][0]
printf("*(int*)(a+1):%d\n", *(int*)(a+1)); //7
printf("*(ptr-1):%d\n", *(ptr-1)); //12-->ptr是一个指针变量,指向的地址中存储的数据是整型
}