Android JNI1--C语言基础

2023-11-19

1,  #include

相当于java的导包操作 例如:#include <stdio.h>

<> 代表寻找系统的资源
“” 代表寻找我们自己写的资源
.h .hpp(声明文件 头文件)
.c  .cpp (实现文件)

2,代码结构

int main() {  // 函数的主入口
    printf("哈喽!");//打印

    getchar(); // 阻塞程序
    return 0;
}

3,基本数据类型

 int i = 100;
 double d = 200;
 float f = 200;
 long l = 100;
 short s = 100;
 char c = 'd';
上面这些基本数据类型与java一致
需要注意的是 字符串类型 java中是String  而C语言中是  char * str = "我是字符串";
sizeof获取字节数 下面是每个基本类型所占用的字节数 可以通过此api获取
sizeof(int)//int 占几个字节  == 4
sizeof(double)//double 占几个字节 == 8
sizeof(char)//char 占几个字节 ==1
sizeof(long)//long占几个字节 == 4
sizeof(short)//short占几个字节 == 2
sizeof(float)//float占几个字节 == 4


 bit——计算机的最小单位

          byte——1byte = 8bit       (byte就是字节)

          kb——1kb = 1024byte

          mb——1mb = 1024kb

          gb——1gb = 1024mb

          tb——1tb = 1024gb

          pb——1pb = 1024tb

4,打印

打印需要注意的是,不和java一样随便打印的,需要占位符

    printf("i的值是:%d\n", i); // d == 整形
    printf("d的值是:%lf\n", d); // lf == long float
    printf("f的值是:%f\n", f); // f == float
    printf("l的值是:%d\n", l); // d == 整形
    printf("s的值是:%d\n", s); // s == short
    printf("c的值是:%c\n", c); // c == char
    printf("字符串:%s\n", str); // s == String

5,指针地址

在java中,万物皆对象。

在Linux中,万物皆文件

在C 语言中,万物皆指针

指针其实可以理解为地址

  & 代表取出地址 例如:

int number = 10;
printf("此number变量的地址是:%p\n", &number); // 地址 == 00B3FE90
* 代表取出地址所对应的值 例如:
int number = 100;
printf("number的值是:%d\n", *(&number));//100 

&number代表number所对应的地址  *(&number)代表取number地址所对应的值 所以输出100
int * 代表int类型的指针 说明定义的是一个指针变量,就是一个变量而已,只不过是指针的变量而已

例如:

int a = 100;
int * b = &a;
printf("a的值是:%d\n", *b);

输出100  因为b是a的指针,也就是a地址,
*b代表取地址所对应的值,也就是取a的地址所对应的值100

只要记住一句话,内存地址就是指针,指针就是内存地址

下面看一个错误的用法:

int i = 100;
int * p = i;

这种写法是错误的,因为p只能接收指针,给它传一个100,显然是不行的

正确的写法应该是:

int i = 100;
int * p = &i;
指针变量 只能接收指针

如何通过指针修改变量值呢?举个例子:

int i = 100;
int * p = &i;
i = 200;
printf("*p的值是:%d\n", *p);

输出200,因为i变为了200,p指向i,*p取得是i的值


*p = 300;

printf("i的值是:%d\n", i);


输出300,因为*p代表i的地址所对应的值修改成300

6,函数

C语言不允许函数重载,Java可以,C++可以

函数需要先声明,再实现。 函数不能写在main函数的下面,会报错

下面来看一个简单的函数例子:

#include <stdio.h> //引入标准库

void change(int * i); // 先声明  参数为指针变量

int main() {

    int i = 100;

    change(&i);//传入指针

    printf("%d\n", i);//输出666

    return 0;//main函数返回值 也可以写为NULL
}


// 再实现
// 使用指针 来修改
void change(int * i) {

    *i = 666;
}

由于C语言不支持函数重载,所以声明的函数,不需要写参数

例如:

void change();//不需要填写参数

int main() {
    int a = 100;
    int b = 200;

    change(&a, &b);

    printf("交换完成后的效果:%d,%d\n", a, b);//200  100

}

// 只接收指针(内存地址)
void change(int * a, int * b) {

    int temp = *a;

    *a = *b;

    *b = temp;
}

7,多级指针:

直接看例子:

int num = 20;

int * num_p = &num; // 取出num的内存地址给 num_p(一级指针)

int ** num_p_p = &num_p; // 取出num_p的内存地址给  num_p_p(二级指针)

int *** num_p_p_p = &num_p_p;//取出num_p_p的内存地址给 num_p_p_p (三级指针)

printf("获取最终的值:%d\n", **num_p_p);//输出20

printf("获取最终的值:%d\n", *** num_ppp);//输出20

是几级指针,取值时,前面就加几个*

8,数组与数组指针

 定义数组
 int [] arr = {1,2,3,4}; 错误的写法
 int arr[]  = {1,2,3,4}; 正确写法
遍历数组
int i = 0;
for (i = 0; i < 4; ++i) {
   printf("%d\n", arr[i]); // 取值
}

数组的内存地址 等于第一个元素的内存地址,不是其他元素的地址

上面数组的内存地址可以写为:arr    &arr   &arr[0]

既然数组就是一个内存地址,那么

int * arr_p = arr;

数组可以用地址变量赋值

操作数组,就是对数组的指针进行操作。

int arr[]  = {1,2,3,4};

将数组地址赋值给指针变量arr_p  此时指针默认指向第一个元素
int * arr_p = arr; 

printf("%d\n", *arr_p); //输出1 因为此时指针指向第一个元素的内存地址

arr_p ++; // 指针挪动   此时指向元素二的内存地址了

printf("%d\n", *arr_p); // 输出2 因为此时指针指向第二个元素的内存地址

arr_p += 2;

printf("%d\n", *arr_p); // 输出4 因为此时指针指向第四个元素的内存地址

数组是连续的内存空间,数组每次挪动4个字节

通过循环给数组赋值:

定义数组
int arr[4];

赋值给指针变量arrP
int * arrP = arr;

循环赋值操i作
int i = 0;
for (i = 0; i < 4; ++i) {
  // 1.拿到 元素一 元素二 元素三 元素四 的内存地址   (arrP + i)
  // 2.取出 元素一 元素二 元素三 元素四 的内存地址 所对应的值 * (arrP + i)
  * (arrP +i) = (i + 10001);
}

9,函数指针

void(*methid)(int,int) 函数指针 

void 返回值

(*methid) 函数名

(int,int)参数  可以随便写 这里只是举个例子

下面来看具体用法:

void add(int num1, int num2); // 先声明


void opreate(void(*method)(int,int), int num1, int num2) {
    method(num1, num2);
}


int main() { 

    opreate(add,  10, 10);
   
    printf("main函数的 add指针是多少:%p\n", add);

    // &add和add是一样的值吗
    printf("%p, %p\n", add, &add); //  一样的

    return 0;
}

// 再实现 使用
void add(int num1, int num2) {
    printf("num1 + num2 = %d\n", (num1 + num2));
}

10,C语言中的布尔类型

C语言和Java的不同就是,C语言没有true和false  只有0和非0

只要记住一句话即可,非0即true  0就是false

11,静态开辟

在函数局部内,创建的数据,在执行函数的时候会进栈操作,函数执行完毕,会执行弹栈。因此会释放栈内的成员,栈内的数据也称之为栈内成员,这种方式开辟的内存,称为静态开辟,执行完会弹栈。不会占用内存空间。

静态开辟,即在栈区开辟内存 
int a;
int arr[6];
char 'c';
等等操作都属于静态开辟内存
进栈
void staticAction() {
    int arr[5]; // 静态开辟 栈区 (栈成员)
} 
函数的末尾会弹栈(隐士):执行完毕会弹栈  会释放所有的栈成员
栈区:占用内存大小 最大值: 大概 2M  大于2M会栈溢出  平台有关系的
堆区:占用内存大小 最大值: 大概80%  40M没有任何问题,基本上不用担心 堆区很大的
大概80%: Windows系统 给我们的编译器给予的空间  的 百分之百八十

12,动态开辟

使用malloc函数,可以动态开辟内存,这种方式的空间属于在堆中开辟,函数执行完毕之后,不会释放堆空间,因此我们一定要手动释放free,并把指针指向NULL。避免悬空指针。

悬空指针:指针指向一块内存,如果这块内存稍后被操作系统回收(被释放),但是指针仍然指向这块内存,那么,此时该指针就是“悬空指针”

void *p = malloc(size);
assert(p);
free(p); 
// 现在 p 是“悬空指针”

正确的写法

void *p = malloc(size);
assert(p);
free(p); 
// 避免“悬空指针”
p = NULL;

野指针:是没有被初始化过的指针,所以不确定指针具体指向

void *p;  // 此时 p 是“野指针”

因为“野指针”可能指向任意内存段,因此它可能会损坏正常的数据,也有可能引发其他未知错误。在实际的C语言程序开发中,定义指针时,一般都要尽量避免“野指针”的出现,可通过赋初值方式解决:

void *p = NULL;
void *data = malloc(size);

下面再来讲讲动态开辟:

 int * arr = malloc(1 * 1024 * 1024); // 堆区开辟 4M

 free(arr); // 释放掉
 arr = NULL; // 重新指向一块内存地址00000
realloc:前面已经开辟的空间,使用realloc可以扩展空间大小,举例如下:
动态开辟一个大小为5的数组
int * arr = (int *) malloc(5);
for (int i = 0; i < 5; ++i) {
  arr[i] = (i + 10001); 
}

//使用realloc 将arr扩展为大小为11的数组
int * new_arr = (int *) realloc(arr, 5+6);

int j = 5; // 5开始
for (; j < (5+ 6); j++) { 
   arr[j] = (j + 10001);
}

别忘了释放
free(new_arr);
new_arr = NULL;

13,结构体

在C语言中,结构体相当于 java中的类

结构体的定义形式为


struct 结构体名
{
   成员列表(可以是基本的数据类型,指针,数组或其他结构类型)
};

例如:

struct Dog {
    // 成员
    char name[10];
    int age;
    char sex;

};
必须要在最后写;
struct Dog dog;
这样写完,成员是没有任何初始化的,成员默认值 是系统值,乱码

赋值操作
  
strcpy(dog.name, "旺财");
dog.age = 3;
dog.sex = 'G';

第二种写法:

struct Person {
    // 成员
    char * name; // 字符指针 = "赋值"
    int age;
    char sex;
} ppp = {"zhangsan", 33, 'W'};

结构体指针

struct Cat {
    char name[10];
    int age;
};

int main() { // 栈

    // 结构体
    struct Cat cat = {"小花猫", 2};

    // 结构体 指针    -> 调用一级指针成员
    struct Cat * catp = &cat;
    catp->age = 3;
    strcpy(catp->name, "小花猫2");
    printf("name:%s, age:%d \n", catp->name, catp->age);

    return 0;
}

结构体指针与动态内存开辟

struct Cat {
    char name[10];
    int age;
};

int main() { // 堆

    // VS的写法:Cat * cat = (Cat *) malloc(sizeof(Cat));
    struct Cat *cat = malloc(sizeof(struct Cat));

    strcpy(cat->name, "金色猫");
    cat->age = 5;

    printf("name:%s, age:%d \n", cat->name, cat->age);

    // 堆区的必须释放
    free(cat);
    cat = NULL;

    return 0;
}

14,结构体取别名

struct Student_{
    char name[10];
    int age;
    char sex;
};

typedef struct Student_Student_; // 给结构体取别名

typedef Student_* Student; // 给结构体指针取别名

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android JNI1--C语言基础 的相关文章

  • 如何创建在 React-Native 中检测自动位置的地图

    我已经在react native中创建了地图 参考https github com lelandrichardson react native maps https github com lelandrichardson react nat
  • Android EditText 和 addTextChangedListener

    我目前正在将数据库管理器移植到 Android 由于性能原因 我喜欢 仅更新已修改的属性 我尝试使用 addTextChangedListener 执行此操作 以便将修改后的条目添加到列表中 但我的程序从未输入其任何方法 EditText
  • 通过代码在创建时突出显示 ListView 项目

    我想在创建 listView 时突出显示 ListView 的第一行 0 我尝试了不同的方法 就像您在注释代码中看到的那样 但没有任何效果 这很奇怪 因为 OnItemClickListener 中的突出显示工作正常 它通过 xml 选择器
  • 使用同一个侦听器的多个活动

    我有 4 个活动 它们都包含一个 xml 页脚 其中包含 4 个按钮 每个活动一个 我现在想为这些按钮设置 onclicklistener 它是页脚中的自制菜单 问题是 如何使用侦听器以便重用代码 我有两个想法 创建一个实现 onclick
  • Android Camera.takePicture() 有时不返回?

    我正在编写一个Android 拍照应用程序 该代码在 onPreviewFrame byte data Cameracamera 中从预览中获取帧后进行一些处理 问题在于 android hardware Camera 的函数 takePi
  • 如何在 Android 应用程序中隐藏 Flutterwave API 密钥

    我正在构建一个 Android 应用程序 目前正在将 Flutterwave 集成到我的应用程序中以进行支付 建议我永远不要将 Flutterwave API 密钥放在我的应用程序上 那么我该如何隐藏这些键呢 我正在使用 Retrofit
  • Android 中使用黑白 alpha 蒙版的高效位图蒙版

    我想用黑白 alpha 蒙版来掩盖位图 我的蒙版图像是黑白的 黑色区域意味着透明 白色区域意味着不透明 我需要的是 当我使用此蒙版图像来蒙版任何其他图像时 如果蒙版图像的相应区域为黑色 则生成的图像区域应为透明 否则 生成的图像区域应该是不
  • 如何清除Android剪贴板?

    我发现的方法都不起作用 这是我尝试过的 1 使用clearPrimaryClip 的方法ClipboardManager class ClipboardManager clipboard ClipboardManager getSystem
  • 如何绘制部分位图圆弧?类似于圆形进度轮,但具有显示得越来越多的位图。

    我正在寻找的是一种以顺时针圆形方式显示图像的视图 当进度为 25 时 应显示前 90 度 当进度为 100 时 应绘制完整的 360 度 它与使用 canvas drawArc 非常接近 但此方法仅适用于 Paint 对象 不适用于位图 其
  • 在光标所在行强制关闭!

    嘿 我正在尝试创建一个应用程序来查找存储在 SQlite 数据库中的 GPS 数据 但我面临一个问题 我构建了一个 DbAdapter 类来创建数据库 现在我尝试使用以下函数从另一个类获取所有数据上的光标 public Cursor fet
  • 如何在 60 分钟后删除共享首选项

    我想存储登录数据 但希望在 60 分钟后删除该数据 执行此操作的正确方法是什么 在这 60 分钟内可以关闭 停止 打开应用程序 我不想使用内部数据库 这是我的访问代码SharedPreferences sharedpreferences g
  • 如何在同一设备上运行的 Android 应用程序之间传输文件?

    我正在编写一个与 RESTful 服务交互的 Android 应用程序 该 Web 服务本质上是一个文件系统 并提供元数据以及对文件的 CRUD 访问 我的应用程序检索元数据 并通过ContentProvider 我需要添加与我的应用程序在
  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • Expresso 的 Android 测试首选项片段

    我在通过 Expresso 测试我的代码时遇到问题 我写了这段代码 public class SettingsActivity extends Activity Override protected void onCreate Bundle
  • TextView.setMaxLines 不起作用?

    在我的应用程序中 我有一个屏幕 其中显示一些文本 然后显示一张照片 文本的长度是可变的 有时根本没有 有时很多 所以我想对其进行设置 以便文本永远不会占用超过几行 但可以滚动 为下面的图像留下足够的空间 我这部分的视图组件是以编程方式创建的
  • 了解应用程序在后台时何时收到 Firebase 消息

    我知道这个标题有同样的问题 但不幸的是它没有得到正确的回答 它被接受了 here https stackoverflow com questions 37711082 how to handle notification when app
  • XML 配置中的 screenName 不起作用

    我刚刚在我的应用程序中添加了对 Google Analytics 分析 的支持 但我无法
  • onPrepareOptionsMenu 复制 ActionBar 中的项目

    当我使用 onPrepareOptionsMenu 添加菜单项时 该菜单项会在操作栏中复制其自身 我正在使用片段并在主要活动的 ActionBar 中创建初始菜单 如下所示 Override public boolean onCreateO
  • 如何从DataSource.Factory获取数据

    我必须调用此方法才能获取所有人员 我根本无法修改这个方法 Query SELECT FROM PERSON TABLE ORDER BY NAME DESC abstract fun getElements DataSource Facto
  • 我想测量 ListView 的高度 (getHight() = 0)

    我无法自己决定任务将是问 我想测量 ListView 的高度 无法捕捉渲染 ListView 的时刻 rssListView getHight 0 public class RSSactivity extends Activity publ

随机推荐

  • template 的使用

    插件介绍 template 是一个高性能的JavaScript模板引擎 插件特性 1 性能卓越 执行速度快 mustache 与 tmpl 的20多倍 2 支持运行时调试 可精准定位异常模板所在语句 3 对 NodeJS Express 有
  • Java NIO Files类读取文件流方式详解

    Java NIO Files类读取文件流方式详解 Files类原理概述 java nio file Files是Java标准库提供的一个工具类 用于操作文件和目录 它提供了一系列静态方法 可以用于创建 复制 删除 移动 重命名 读取 写入文
  • Kaggle研究16,000+数据科学从业者并公开数据 !(附数据集下载)

    来源 机器之心 本文长度为2540字 建议阅读5分钟 本文整理Kaggle对人工智能领域超过16 000受调查者的调查数据结果 Kaggle 是互联网上最著名的数据科学竞赛平台之一 今年3月8日 这家机构被谷歌收购 6月6日又宣布用户数量超
  • 二进制.bin文件切分、bintopng、write

    import numpy as np import cv2 import os Your file path file dep open r E data 3DHuman Detection withoutlabel 20180715 50
  • 小白入门机器学习深度学习实战教程

    课程介绍 机器学习深度学习 实战训练营开课了 哔哩哔哩 bilibili 机器学习深度学习 实战训练营开课了
  • Leetcode——350. 两个数组的交集 II

    题目 给你两个整数数组 nums1 和 nums2 请你以数组形式返回两数组的交集 返回结果中每个元素出现的次数 应与元素在两个数组中都出现的次数一致 如果出现次数不一致 则考虑取较小值 可以不考虑输出结果的顺序 输入 nums1 1 2
  • 关于gitee的用法

    一 安装git 安装git git version 查看版本 创建仓库 git 全局配置 git config global user name huangkaihk git config global user email 邮箱 git
  • 2.6.1 ADSL技术

    ADSL技术 即 非对称数字用户线技术 利用 数字技术 对 现有的 模拟电话用户线 进行改造 使其能够承载宽带数字业务 标准模拟电话信号的 频带 被限制在 300 3400 Hz 的范围内 无法承载宽带数字业务 但 用户线本身 可通过的 信
  • 超详细!4小时开发一个SpringBoot+vue前后端分离博客项目!!

    小Hub领读 前后端分离的博客项目终于出来啦 真是花了好多心思录制咧 文末直接进入B站看视频哈 这次你找不到不关注我B站的理由了吧 作者 吕一明 项目代码 https github com MarkerHub vueblog 项目视频 ht
  • Unity卡死情况

    今天遇到了Unity点击播放后卡死 用任务管理器强行关闭后重开 打不开项目的情况 解决方案 检查USB接口设备 有些设备可能会影响Unity工程启动 比如VR头盔
  • 使用java代码给Excel加水印,代码全,进阶版

    以下代码 亲测可以跑通 1 上一篇博客用了Apache POI库3 8的版本的形式对Excel加了水印 但是最近主线版本用了4 1 2的形式 由于为了保持版本的兼容性 下面有开发了Apache POI的4 1 2的版本号的方案 pom文件为
  • 使用selenium IDE开始简易自动化测试

    使用selenium IDE开始简易自动化测试 火狐浏览器有个很好用的selenium插件 可以自动录制页面动作 selenium IDE 下载地址 下载安装好 笔者下载的2 9 0 我们以在百度搜索selenium为例 首先启动IDE 点
  • 链式二叉树的基本操作(C语言实现)

    目录 一 链式二叉树的创建 1 1 定义节点结构 1 2 节点的创建 1 3 节点的链接 二 树的深度遍历 1 前序 中序 后序遍历 1 2 三种方式的遍历顺序图 2 代码实现 3 遍历检测 三 树的层序遍历 3 1 层序遍历 3 2 完全
  • Loadrunner录制登录,验证是否登录成功的几种方法

    1 利用web reg find 优先使用 2 利用web image check 其次 3 利用web get int property函数 4 利用提交的status状态 5 利用对数据的操作查看是否登录 1 利用添加检查点web re
  • 拼多多招收java开发的三轮面试题,你能撑到第几轮?

    我相信 面试一直是大家关注的问题 包括最近有很多刚毕业或者刚实习的小伙伴跟我讲投了很多简历出去 但却都像泥牛入海一样了无音讯了 确实出于程序员的直觉 今年着实是要比往年要更冷一些 对于面试来说 我相信大家都听过一个说法就是 金九银十 但是现
  • c++/cuda并行累计求和

    文章目录 代码 CMakeLists txt 结果 代码 include
  • 设计模式-建造者模式

    文章目录 建造者模式 创建复杂对象的优雅方式 什么是建造者模式 建造者模式的使用场景 优缺点 示例 使用建造者模式创建电脑对象 建造者模式 创建复杂对象的优雅方式 在软件开发中 有时候我们需要创建具有复杂结构和多个组件的对象 直接在客户端代
  • 【Pytorch异常笔记】Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.

    文章目录 异常描述 解决方法 开发环境 异常描述 OMP Error 15 Initializing libiomp5md dll but found libiomp5md dll already initialized OMP Hint
  • git 和远程服务器关联,Git远程服务器连接被拒绝

    我对这个错误感到疯狂 2天后我没有发现我的系统出了什么问题 我相信修复它非常容易 Git远程服务器连接被拒绝 当我尝试使用Git功能我得到的消息 连接到我的git服务器 无法打开连接 主机不存在 致命的 无法从远程存储库中读取 请确保您拥有
  • Android JNI1--C语言基础

    1 include 相当于java的导包操作 例如 include