基本步骤:
1、将好久没有更新过的VS先更新一下
2、安装C语言开发需要的组件
3、去网上简单回顾下C语言的语法
新建一个C++的空项目,VS没有新建C的项目。因为C++是完全兼容C的所有直接新建C++项目是没有问题的。

在源文件添加一个新建项hello.c,随便打印一个hello。
#include <stdio.h>
int main() {
printf_s("%s", "hello");
return 0;
}
printf_s() 是printf的安全版本,在VS2017中已经不允许使用printf(),其他版本能不能用目前没有验证过。
#include <stdio.h>
int main() {
int a,* a_ptr; // 随便定义一个变量a和一个a_ptr指针
a = 9527;//给a赋值
a_ptr = &a; // &变量 表示取变量的地址
printf_s("变量a地址:%p\n",a_ptr); // 将指针的值打印出来,这个值就是代表了变量a的内存地址
printf_s("a_ptr指针对应地址的值:%d", *a_ptr); // 将a_ptr 进行解引用输出指针对应地址的值
return 0;
}
其实直接看上面的代码也不难理解了,&表示取地址,*表示取值
上面的代码定义了一个变量和一个指针,先给变量赋值为9527。接着将a变量的地址给a_ptr指针
我们直接把一个变量赋值给指针的值会发生什么呢?
#include <stdio.h>
int main() {
int a,* a_ptr; // 随便定义一个变量a和一个a_ptr指针
a = 9527;//给a赋值
*a_ptr = a; // 直接将a赋值给指针的值
return 0;
}

上面的代码直接报错了,因为指针没有初始化
我们继续尝试,如果将一个变量的值赋值给一个指针会发生什么,我们看看下面的代码
int main() {
int a,* a_ptr; // 随便定义一个变量a和一个a_ptr指针
a = 9527;//给a赋值
a_ptr = a; // 直接将a赋值给指针的值
printf_s("%p", a_ptr);
return 0;
}

打印地址可以看到输出的2537,9527的16进制就是等于2537,可以看到是完全没有问题的。
我们再来看看数组
#include <stdio.h>
int main() {
float a[5] = { 0,1.0,2.0,3.0,4.0 };
printf_s("数组的起始地址:%p\n数组的第三个元素:%f\n数组占用多少字节%d", a, *(a + 2), sizeof(a));
return 0;
}

可以看到数组a输出的是一个指针地址,在C语言可以通过
a[0] // a[下标]的方式进行取值
也可以向上面代码一样通过指针偏移进行取值,a+1偏移的地址是数组类型对应的字节数,int类型偏移4个字节,cha类型偏移1个字节,数组元素都是连续存储的,地址依次从低到高。上面数组的值应该是
a = 00F7FECC; // 数组a的地址
[*(a),*(a+1),*(a+2),*(a+3),*(a+4)];
接下来我们再看看二维数组
#include <stdio.h>
int main() {
int a[2][3] = { {0,1,2}, {4,5,6} };
printf_s("数组的起始地址:%p\n数组的第二个元素:%p\n数组占用多少字节%d\n", a, *(a + 1), sizeof(a));
return 0;
}

上面我们可以看到这是一个二维数组,int占4个字节,总共6个元素,所用总共占用了24个字节。当我们打印第二个元素的时候发现也是一串地址,应该可以得出a是一个二级指针。这时候我们需要怎么取值呢。
*(*a) // 先使用一个*取二维数组的地址,然后再用一个*取二维数组的第一个元素的值
根据上面的语法我们来试一下,代码如下:
#include <stdio.h>
int main() {
int a[2][3] = { {0,1,2}, {4,5,6} };
// printf_s("数组的起始地址:%p\n数组的第二个元素:%p\n数组占用多少字节%d\n", a, *(a + 1), sizeof(a));
printf_s("取第一个数组的第二个元素值:%d",*(*a + 1));
return 0;
}
前面我们一直都是再获取值,下面看看怎么改值:
#include <stdio.h>
int main() {
int a[2][3] = { {0,1,2}, {4,5,6} };
// printf_s("数组的起始地址:%p\n数组的第二个元素:%p\n数组占用多少字节%d\n", a, *(a + 1), sizeof(a));
*(*a + 1) = 7; // 将第一个数组的第二个元素值修改成7
printf_s("取第一个数组的第二个元素值:%d",*(*a + 1));
return 0;
}

基本到这里就差不多了,其实本篇文章的目的是为了看懂下面一段Android源码:

readUnsignedLeb128(const u1** pStream)
函数是有个二级指针pStream的参数
首先先解释一下u1类型,u1表示一个字节无符号数
const u1* ptr = *pStream;
将pStream 进行解引用,赋值给一级指针ptr
int result = *(ptr++);
将指针ptr偏移一个字节并解引用。赋值给result
if(result>0x7f){
...
}
这个目的是判断字节最高位是否为1,到这里关于指针的部分就so easy了,剩下的就是一些位的操作,就不讲了

将自己学习的过程记录下来也是一种学习,文章里有不对的地方欢迎指出
网友评论