字符操作
- 字符数组
#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中的类,只不过这个类比较特殊,结构体中只有申明,函数没有实现,变量不能初始化,一般定义在头文件中,类似于声明了一个抽象类。
一个小例子:
#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*);
};