C语言入门
从现在开始准备学习ndk开发,从基础开始学习和记录,大神勿喷,如有不对的地方,可以指出,谢谢
C 面向过程,一个一个的执行函数,没有类,没有面向对象
C++ 面向对象,思想和java的一摸一样 开始有class了
数据类型
有符号(默认定义的变量,是有符号的) 和 无符 。
有符号和无符号的区别: 取值范围不一样。占位打印也不一样
有符号
int类型占位打印 %d ;类型占用4个字节;
short类型占位打印 %hd ;类型占用2个字节
long类型占位打印 %ld ;类型占用4个字节;
char类型占位打印 %c ;类型占用1个字节;
int count = 99; //默认有符号的 相当于 signed int count = 99;
// int类型占位打印 %d
printf("int count = %d\n",count);
unsigned int num = 98; //表示无符号
short count_short = 88;
printf("short count_short = %hd\n",count_short);
// long类型占位打印 %ld
long number = 1232334;
printf("long number = %ld\n",number);
// char类型占位打印 %c
char sex = 'w';
printf("char sex = %c\n",sex);
无符号的
long 和 int 都是4个字节,它们有什么意义?
答:long类型 和 int类型,在早期16为电脑的时候 int是2字节,long是4字节,而计算机经过多年的发展,一般是32位,64位,就造成了int 和 long一样长了
无符号 int类型占位打印 %u 占用4个字节;
无符号 short类型占位打印 %hu 占用2个字节;
无符号 long类型占位打印 %ld 占用4个字节,java中占用8个字节;
char类型占位打印 %c //占用1个字节
long long 占用8个字节
// TODO 无符号的输出 打印占用字节数 ,统一的级别都可以用 %d
unsigned int count = 99;
// 无符号 int类型占位打印 %u 4个字节
// %d == 内部转型 u --> d
printf("int count = %u,占用字节数:%d\n",count , sizeof(count));
// int32_t 4个字节 相当于int
int32_t count32 = 10;
// int64_t 8个字节 相当于longlong
int64_t count64 = 11;
// int8_t 1个字节 相当于signed char
int8_t count8 = 12;
// int16_t 2个字节 相当于short
int16_t count16 = 13;
// 无符号 short类型占位打印 %hu 2个字节
// %d == 内部转型 hu --> d
unsigned short count_short = 88;
printf("short count_short = %hu,占用字节数:%d\n",count_short, sizeof(count_short));
// 无符号 long类型占位打印 %ld 4个字节,java中占用8个字节
// %d == 内部转型 lu --> d
unsigned long number = 1232334;
printf("long number = %lu,占用字节数:%d\n",number, sizeof(number));
// char类型占位打印 %c //占用1个字节
unsigned char sex = 'w';
printf("char sex = %c,占用字节数:%d\n",sex, sizeof(sex));
//long 和 int 都是4个字节,它们有什么意义?
//早期电脑16位 int占2个字节; 64位 long 和 int 都是4个字节
//C99 的标准:long 最小要为int 占用字节数
/**
* long类型 和 int类型,在早期16为电脑的时候 int是2字节,long是4字节,
* 而计算机经过多年的发展,一般是32位,64位,就造成了int 和 long一样长了
*/
//修改long的字节
long long num = 456456; //8个字节 == java中的Long
printf("long long num = %ld,占用字节数:%d\n",num, sizeof(num));
布尔类型
非0 就是true ,等于0就是false
非NULL 就是true, 等于NULL就是false
// TODO 布尔类型
// 非0 就是true ,等于0就是false
// 非NULL 就是true, 等于NULL就是false
if(9){
printf("不等于0就是true\n");
}else{
printf("等于0就是false\n");
}
浮点类型
float类型占位打印%f
float类型占用4个字节
.2 表示只输出后面小数点 位数
// TODO 浮点类型
// float类型占位打印 %f 4个字节
float f01 = 123234.12;
printf("float f01 = %f,占用字节数:%d\n",f01, sizeof(f01));
// double类型占位打印 %lf 8个字节 双进度
double d01 = 121445.12;
printf("double d01 = %lf,占用字节数:%d\n",d01, sizeof(d01));
// long double类型占位打印 %Lf 16个字节
long double ld01 = 14.122121;
printf("long double ld01 = %f,占用字节数:%d\n",ld01, sizeof(ld01));
// .2 表示只输出后面小数点 位数
printf("long double ld01 = %.2f,占用字节数:%d\n",ld01, sizeof(ld01));
字符串
第一种写法 char* str
第二种写法 char * str
第三种写法 char *str (标准写法)
// TODO 字符串
/**
* 第一种写法 char* str
* 第二种写法 char * str
* 第三种写法 char *str
*/
//一级指针 字符串 占位打印 %s 8个字节
char *str = "你好 C和C++....";
printf("char *str = %s,占用字节数:%d\n",str, sizeof(str));
// TODO sprintf
char strChar[200]; //数组 容器 存放
//sprintf这里会把 今天是11号存放到 strChar容器里面去
sprintf(strChar, "今天是%d号\n",11);
printf("char strChar[200] = %s",strChar);
数组
数组是一块连续的内存空间;
*就是取内存地址里面 对应的值
数组的内存地址 和 数组首位的内存地址 一样;
java中写法 int[] test;
这里:
必须这样写 int test[8];
必须给定 存放空间 或者 直接初始化;
记住下面的for循环写法;
// TODO 数组
//java中写法 int[] test;
//这里:
//1、必须这样写 int test[8];
//2、必须给定 存放空间 或者 直接初始化
int test[8]; //给定存放空间
int test2[] = {1,2,3,4,7}; //直接初始化
//这里输出 长度20 因为1个int数是 4个字节 上面有5个数字
printf("数组的长度%d\n", sizeof(test2));
//输出1
//TODO 1、数组是一块连续的内存空间
//TODO *就是取内存地址里面 对应的值
//TODO 数组的内存地址 和 数组首位的内存地址 一样
//* (test2 + 0) 表示 出去 数组第一位内存空间 所对应的值 *就是取内存地址里面 对应的值
printf("数组下标1 %d\n",* (test2 + 0));
printf("数组下标2 %d\n",* (test2 + 1));
//遍历
/**
* VS 的写法,需要把int i 定义到外面
*/
// int i;
// for (i = 0; i < 10; ++i) {
//
// }
// TODO C 和 C++
// TODO C 面向过程,一个一个的执行函数,没有类,没有面向对象
// TODO C++ 面向对象,思想和java的一摸一样 开始有class了
//(sizeof(test2) / sizeof(int)) 20/4 也就是总字节数 除以 int类型的占用字节数 = 这里等于5
// 这里就是循环5次
for (int i = 0; i < (sizeof(test2) / sizeof(int)); ++i) { //循环5次
//理解:数组是一块连续的内存空间,才能通过*取出内存地址对应的值 打印出来
printf("遍历数组下标:%d *对应的值是:%d\n", i ,* (test2 + i));
//传统方式
printf("传统方式,数组的值:%d\n",test2[i]);
//数组的内存地址 %x 打印内存地址 加一个# 表示以16进制展示 0x61fcd0 0x61fcd4 0x61fcd8 0x61fcdc 0x61fce0
//因为 int是4个字节 所以跨度在4
printf("遍历数组下标:%d 对应的内存地址:%#x\n", i ,(test2 + i));
}
动态内存申请
堆区和栈区的区别 栈区的内存没有堆区大 如果很大的内存 是需要在堆区申请的,否则是可以在栈区
calloc:动态内存申请,记得引入头文件#include <stdlib.h>;
动态内存申请的都是在 堆区;
动态内存申请 堆区申请 申请的内存记得 清空和释放内存 不然会一直占用内存;
动态申请的时候,内部会去检测,是否有可以用的内存,拿来用 ,有可能会拿到 别人玩剩下的,就有可能有值,所以记得要清空 和 释放;
// TODO 悬空指针 这样定义的都是在 栈区 ; 动态内存申请的都是在 堆区
int *p1; //悬空指针 这样定义的都是在 栈区
long * l1; //悬空指针 这样定义的都是在 栈区
//TODO 动态内存申请 堆区申请 申请的内存记得 清空和释放内存 不然回一直占用内存
// calloc 记得导入头文件 #include <stdlib.h> 返回的是一个 指针类型
//表示在堆中申请 40个字节的空间 int是四个字节 申请10个
/**
* 动态申请的时候,内部会去检测,是否有可以用的内存,拿来用
* 有可能会拿到 别人玩剩下的,就有可能有值,所以记得要清空 和 释放
*/
int *p3 = calloc(10, sizeof(int));
//初始化 为了清空 申请的内存空间,清空是为了防止有脏数据
memset(p3,NULL,10 * sizeof(int));
//释放空间内存
free(p3);
// p3 ===野指针
p3 = 0; //也可以 p3 = NULL
//TODO 堆区和栈区的区别 栈区的内存没有堆区大 如果很大的内存 是需要在堆区申请的,否则是可以在栈区
辛苦各位童鞋观看到最后,如果博客中有不对的地方望指出,大神勿喷,谢谢~~