Android NDK开发(二)C语言基础语法

接上篇Android NDK开发(一)C语言基础语法

字符操作

  • 字符数组
#include<stdio.h>
    void charArray(){
    char c[15] = {'h','e','l','l','o','w','o','r','l','d'};
    printf("%s\n",c);
    c[0] = 'a',
    printf("修改之后的内容是:%s\n",c);
}
int main(){
    charArray();
}

这里写图片描述
字符数组本身也是一个数组,但是可以作为字符串格式化输出。可以提换里面任意的字符。

  • 字符指针
#include<stdio.h>
void charArray(){
    char c[15] = {'h','e','l','l','o','w','o','r','l','d'};
    printf("%s\n",c);
    c[0] = 'a',
    printf("修改之后的内容是:%s\n",c);
}
void charPointer(){
    char* s = "永不言弃\n";
    printf("内存地址是:%#x\n",s);
    s+=6;
    while(*s){
      printf("%c",*s);
      s++;
    }
}
int main(){
    charPointer();
}

这里写图片描述
我们会发现内容不全,这是因为,对于字符指针来说,我们不能修改,就只会保留最后一次修改的值,大小也是固定的。类似于String和StringBUffer,String定义了之后就没有办法修改里面的内容,但是StringBuffer却可以修改。
关于字符串的操作:
1.拼接字符串

2.查找单个字符

3.查找字符串

4.字符转换

5.字符转换函数定义

#include<stdio.h>
void spliceString(){
  char dest[40] = {'h','e','l','l','o'};
  char* c1 = "never give up";
  char* c2 = "i love you!";

  //方法strcpy会清除数组中原有的数据
  strcat(dest,c1);
  strcat(dest,c2);

  printf("\n拼接字符串:\n%s\n",dest);
}

void searchChar(){

  char* str = "all my friend the night is young";
  char* p = strchr(str,'d');
  if(p){
    printf("索引的位置是:%d\n",p - str);
    printf("打印:");
    str += p - str;
   while (*str){
      printf("%c",*str);
      str++;
    }
    printf("\n");
  }else{
    printf("没有找到\n");
  }
}

void searchChars(){
  char* str = "wo are loading!";
  char* handle = "are";
  char* p = strstr(str,handle);
  if(*p){
    printf("索引为止:%d\n",p - str);
    printf("打印:");
    str += p - str;
    printf("%s ---- %s\n" ,str,p);
  }else{
    printf("没有找到\n");
  }
}

void strToInt(){
  //字符转换
  char* p = "123";
  int toInt = atoi(p);
  int res = toInt + 100;
  printf("字符转换之后int数值是:%d\n",res);
}


int main(){
  while(1){
    int num;

    scanf("%d",&num);
    if(num == 1){
      spliceString();
    }else if(num == 2){
      searchChar();
    }else if(num == 3){
      searchChars();
    }else if(num == 4){
      strToInt();
    }else{
      return 0;
    }
  }
}

这里写图片描述
字符串函数比较多,具体可以参考字符串函数

结构体

结构体声明

结构体就是C语言中结构化数据类型的核心。
在java中我们通常是这样写的

public class Persion{
    private String name;
    private int age;
}

这种javabean的写法在C语言中就是结构体,我们使用关键字struct

struct Persion{
    char* name;
    int* age;
}

我们是可以将C语言中的结构体自比成java中的类,只不过这个类比较特殊,结构体中只有申明,函数没有实现,变量不能初始化,一般定义在头文件中,类似于声明了一个抽象类。
一个小例子:

扫描二维码关注公众号,回复: 2630350 查看本文章
#include<stdio.h>
struct Person{
  char* name;
  int age;
};

struct News{
  char title[128];
  char* content;
};

void makeSinpleStruct(){
  struct Person person = {"牛谱乐",25};
  printf("姓名-%s;年龄-%d\n",person.name,person.age);

  struct Person person2;
  person2.name = "小牛大帝";
  person2.age = 26;
  printf("\n姓名-%s;年龄-%d\n",person2.name,person.age);

  struct News new;
  strcpy(new.title,"这是标题");
  new.content = "具体内容";

  printf("\n标题-%s;内容-%s",new.title,new.content);
}

int main(){
  makeSinpleStruct();

}

这里写图片描述

有两种创建构造体的方法,字面量方式创建;通过定义结构体变量然后给成员变量赋值
数组赋值的时候不要直接通过="",要通过strcpy()的方式

#include<stdio.h>
//结构体的多种写法
//在声明结构体的时候,定义结构体变量和指针(这种情况,表明你知道自己需要执行什么样的操作)
struct Person{
  char* name;
  char* school;
}person,*person1;

//匿名结构体,没有结构体名称,可以定义多个结构体变量,可作为单例使用
struct {
  char* title;
  char* content;
}news;

int main(){
  person.name = "张三";
  person.school = "北京大学";

  printf("人员信息:姓名-%s;学校-%s\n",person.name,person.school);

  person1 = &person;
  printf("人员信息:姓名-%s;学校-%s\n",person1->name,person1->school);

  news.title = "重大新闻";
  news.content = "内容提要";
  printf("新闻:标题-%s;内容-%s\n",news.title,news.content);
  return 0;
}

这里写图片描述

结构体指针操作符使用->,相当于(*p)

结构体嵌套

#include<stdio.h>
/*结构体嵌套 , 两种嵌套方式*/
struct Product {
    char* productName;
    char* productDesc;
};

// one
struct GoodsBean {
    int total;
    int status;

    struct Goods {
        char* goodsName;
        char* goodsDesc;
    };
};

// two
struct ProductBean
{
    int total;
    int status;

    struct Product product;
};

/*结构嵌套示例*/
void nestingStruct() {
    // one
    printf("\n\n\n\n结构嵌套示例\n\n");
    // 使用字面量的形式赋值
    struct GoodsBean goodsBean = { 10,0,{ "全新Iphone6s","金色全新Iphone6s , 能与Android手机媲美的Iphone6s" } };
    printf("商品总数:%d\n商品状态:%d\n商品名称:%s\n商品描述:%s\n", goodsBean.total, goodsBean.status, goodsBean.goodsName, goodsBean.goodsDesc);

    // two
    printf("\n\n");
    struct ProductBean productBean;
    productBean.total = 100;
    productBean.status = 0;
    productBean.product.productName = "金色经典 , 小米5 , 你值得拥有";
    productBean.product.productDesc = "全新金色小米5 , 刚买没几个月";

    printf("商品总数:%d\n商品状态:%d\n商品名称:%s\n商品描述:%s\n", productBean.total, productBean.status, productBean.product.productName, productBean.product.productDesc);
}

int main(){
  newstingStruct();
  return 0;
}

结构体数组

#include<stdio.h>
struct p{
    char* name;
    int age;
};

void useStructArray(){
    struct p p1[] = { {"张三",20},{"李四",21},{"王五",22},{"赵六",23} };
    struct p *p2 = &p1;
    int personArrSize = sizeof(p1) / sizeof(struct p);
    for(;p2<p1+personArrSize;p2++){
       printf("姓名-%s;年龄-%d",p2->name,p2->age);
       printf("\n");
    }
}

int main(){
    useStructArray();
}

这里写图片描述

结构体动态分配内容

#include<stdio.h>
#include<stdlib.h>
struct Man{
  char* name;
  int age;
};
//动态分配内存
void structAndMalloc(){
  struct Man* man1 = (struct Man*)malloc(sizeof(struct Man) * 10);
  struct Man* man2 = man1;
  man2->name = "张三";
  man2->age = 21;
  man2++;
  man2->name = "李四";
  man2->age = 22;

  struct Man* loop_man = man1;

  for(;loop_man < man1 + 2;loop_man++){
    printf("姓名:%s \t 年龄:%d\n",loop_man->name,loop_man->age);
  }
}
int main(){
  structAndMalloc();
}

这里写图片描述

因为动态申请的内容返回的指针是内存空间的首地址,所以我们可以通过man2++的方式进行赋值
遍历动态内存中的数据时,需要从首地址开始遍历,所以需要多次将首地址的值赋值给不同的变量

结构体和函数指针

#include<stdio.h>
struct Dog{
  char* name;
  int age;
  void(*dogWow)(char* wow);
};
void dogWow(char* wow){
  printf("小狗叫:%s \n",wow);
}
void userStructAndFunction(){
  //结构体重,函数没有实现,在创建结构体时,将函数名称赋值给函数指针即可
  struct Dog dog = { "大黄",2,dogWow };
  dog.dogWow("旺旺。。。");
}
int main(){
  userStructAndFunction();
}

这里写图片描述

因为结构体中不能有函数实体,所以我们直接将函数指针传递过去就可以了。

类型别名

使用关键字typedef

不同的名称代表不同的事情 typedef int jint;
不同情况下使用不同的别名
书写简单

#include<stdio.h>
//简单别名
typedef char* Name;
//结构体别名
typedef struct ImageInfo {
  char* name;
  int size;
  char* path;
}ImageInfo,*imageInfo_P;
//修改文件的名称
void reFileName(imageInfo_P img_p,char* reName){
  img_p->name = reName;
}
//类型别名实例
void sueTypedef(){
  Name name = "小牛大帝";
  printf("类型别名:Name = %s\d",name);

  //结构体别名使用,类似于java对象的使用
  ImageInfo imageinfo;
  imageinfo.name = "蓝天.png";
  imageinfo.size = 1024;
  imageinfo.path = "测试内容";

  printf("文件内容:文件名-%s;大小-%d;路径-%s\d",imageinfo.name,imageinfo.size,imageinfo.path);
}
int main(){
  sueTypedef();
}

这里写图片描述
看了挺多的C语言基础,其实还没有跟JNI有关联,在实际中,最重要的便是jni.h这个文件,里面都是结构体,下面是里面的内容

/*
 * JNI invocation interface.
 */
struct JNIInvokeInterface {
    void*       reserved0;
    void*       reserved1;
    void*       reserved2;

    jint        (*DestroyJavaVM)(JavaVM*);
    jint        (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
    jint        (*DetachCurrentThread)(JavaVM*);
    jint        (*GetEnv)(JavaVM*, void**, jint);
    jint        (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
};

猜你喜欢

转载自blog.csdn.net/weixin_42580207/article/details/80904163
今日推荐