首页 > 代码库 > C语言基础
C语言基础
C语言
C语言入门 ( * )
电闸 -> C -> C++ -> java ->C#
Hello.c 编译后的结果 Hello.exe
如果Eclipse不能正常打开 尝试的删除配置文件Eclipse.ini
环境变量classPath 分号前面有一个点 代表的是当前目.;%JAVA_HOME%lib;%JAVA_HOME%lib\tools.jar
#include<stdio.h> //导入了标准的输入输出流函数库 import java.XXX.ooo
#include <stdlib.h> // 导入标准的类库
main(){ // public static void main(String[] args)
printf("Hello world\n" ); // System.out.print
system("shutdown -s"); // c代码 调用java代码
system("pause"); // 调用了系统的指令 让程序 暂时停下来 方便观察程序的结果
}
基本数据类型 ( ***** )
Java语言
类型 | 字节 |
byte | 1 |
short | 2 |
char | 2 |
int | 4 |
long | 8 |
float | 4 |
double | 8 |
boolean | 1 |
char, int, float, double, long, short, signed, unsigned and void
sizeof() 输出类型的长度
c语言中char 占1个字节 java中占2个字节
C99标准语言中int short float double 所占的字节数和java语言占的字节数 一模一样
C99标准语言中long 占4个字节 java中long 占8个字节 //long long // long类型不能比int短
C99标准 没有byte java中byte占1个字节 可以用c语言中 char类型
c语言没有boolean 0 false 1true
while(1){
}
while(true){
}
signed 默认 有符号的 本身不会修改类型的长度
unsigned 无符号 第一位不是符号位 所有的数都是正数
void 不确定长度
#include<stdio.h>
#include <stdlib.h>
main(){
printf("char类型的长度%d\n",sizeof(char)); //%d 占位符 类似sql语句 ?
printf("int类型的长度%d\n",sizeof(int));
printf("float类型的长度%d\n",sizeof(float));
printf("double类型的长度%d\n",sizeof(double));
printf("long类型的长度%d\n",sizeof(long));
printf("short类型的长度%d\n",sizeof(short));
printf("signed int类型的长度%d\n",sizeof(signed int));
printf("unsigned int类型的长度%d\n",sizeof(unsigned int));
system("pause"); // 调用了系统的指令 让程序 暂时停下来 方便观察程序的结果
}
输出 ( ** )
#include<stdio.h>
#include <stdlib.h>
main(){
int i=314151;
short s=314 ;
float f=3.14;
double d=3.141592653;
char c=‘a‘;
printf("int i的值为%d\n",i);
printf("short s的值为%hd\n",s);
printf("float f的值为%f\n",f);
printf("double d的值为%lf\n",d);
printf("char c的值为%d\n",c);
char cstr[]={‘h‘,‘e‘,‘l‘,‘l‘,‘o‘,‘\0‘,‘a‘,‘b‘}; //如果碰到\0 认为字符数组结束了
printf("字符串的值为%s\n",cstr); // c 语言不会数数
system("pause");
}
输入函数 ( ** )
#include<stdio.h>
#include<stdlib.h>
/*
scanf();
& 取地址的符号
*/
main(){
int i; // 用来接受录入的数字
scanf("%d",&i); // 录入一个整数 存放到i的空间中
printf("int i的值%d\n",i);
// 录入字符串
char str [] ={‘ ‘,‘ ‘,‘ ‘,‘ ‘};
scanf("%s",&str);
printf("str的值为%s\n",str);
system("pause");
}
指针 ( ***** )
指针就是内存地址 内存地址 表示内存的编号
存放地址的变量叫做指针变量
通常把指针变量 简称为指针
#include<stdio.h>
#include <stdlib.h>
main(){
// 声明了一个int类型的变量 别名叫做i 值是3
int i=3;
// &i获得i的地址 把i的地址 存放到了变量中 需要存放到指针变量中
// int* 指针变量 专门用来存放地址
// int* 表示int类型变量的的地址
int* p=&i;
printf("p的值是%#x\n",p); //0x28ff44
system("pause");
}
外挂原理 ( * )
就是修改内存地址的值 郁金香外挂
#include<stdio.h>
#include <stdlib.h>
#include <Windows.h>
main(){
int time=60;
printf("time的地址%#x\n",&time);
while(time>0){
printf("当前剩余时间%d\n",time);
//sleep(5000);
Sleep(5000);
time--;
}
system("pause");
}
深入了解指针 ( **************** )
*号的3种含义
- 代表乘法
3*4=12;
- 表示指针变量类型
int* 在已知类型的后面+* 表示存放该类型的地址的变量
- 取地址中的值
*p *在指针变量前
#include<stdio.h>
#include <stdlib.h>
main(){
// 定义了int类型的变量 i 值3
int i=3;
// 定义了int*类型的变量 p 值i的地址
int* p=&i;
// 取p里面的值(地址)中存放的值
printf("i的值%d\n",i);
printf("p的值%#x\n",p);
printf("*p的值%d\n",*p);
// 修改p的值 i的值会不会变 不会变化
// int j = 4;
// p=&j;
printf("i的值%d\n",i);
// 修改i的值 p的值的会不会变 不会变化
// i=4;
// printf("p的值%#x\n",p);
// 修改i的值 *p的值会不会变 会变化
// i=4;
// printf("*p的值%d\n",*p);
// 修改*p的值 i的值会不会变化 会变化
*p=5;
printf("i的值%d\n",i);
system("pause");
}
多级指针 ( *** )
#include<stdio.h>
#include <stdlib.h>
main(){
int i=3;
// 存放i的地址
int* p = &i; // 1级指针 存放1级指针的地址 需要二级指针 //*p
int** q= &p; // 二级指针 //*(*q)
int*** s = &q; //三级指针 用来存放二级指针的地址 ***s
int**** t = &s; // 4级指针 用来存放三级指针的地址
// 如何用t 去修改i的值 ****t =5;
****t =5;
printf("I的值%d\n",i);
system("pause");
}
指针常见的错误 ( * )
错误1:野指针异常
#include<stdio.h>
#include <stdlib.h>
main(){
int* p; // 如果指针变量没有赋值 随机赋值 野指针
printf("*p的值的%d",*p);
*p=3; // 修改了别的应用程序的中值 默认windos不允许修改其他应用程序内存的值 但是可以提升权限
// 野指针异常 指针变量 一定先赋值 再操作
system("pause");
}
错误2:
#include<stdio.h>
#include <stdlib.h>
// 指针变量的类型 一定要和地址本身的类型匹配
// int* 指针要存放 int类型变量的地址
// short* 要存放 short类型变量的地址
main(){
int i=123123;
short* s=&i;
printf("*s的值%hd\n",*s);
system("pause");
}
交换两个数 ( ******** )
int i=3;
int j=5;
int temp;
temp=i;
i=j;
j=temp;
值传递
子函数不能修改主函数的值
#include<stdio.h>
#include <stdlib.h>
void swap(int i ,int j){
int temp;
temp=i;
i=j;
j=temp;
}
main(){
int i =3;
int j=4;
swap(i,j);
printf("交换后i的值%d\n",i);
printf("交换后j的值%d\n",j);
system("pause");
}
引用传递
可以交换两个数
如果子函数想要修改主函数变量的值 必须获取到主函数变量的地址
#include<stdio.h>
#include <stdlib.h>
void swap(int* i ,int* j){
int temp;
temp = *i;
*i = *j;
*j = temp;
}
main(){
int i = 3;
int j = 4;
swap(&i,&j);
printf("交换后i的值%d\n",i);
printf("交换后j的值%d\n",j);
system("pause");
}
返回多个值
Java 返回集合
#include<stdio.h>
#include <stdlib.h>
// 由于主函数传递过来是一个地址 ,子函数的形参必须用指针变量接受地址
void add2(int* i,int * j){
*i += 2;
*j += 2;
}
main(){
int i = 3;
int j = 5;
add2(&i,&j);
printf("i的值%d\n",i);
printf("j的值为%d\n",j);
system("pause");
}
数组 ( *** )
- 数组中的所有元素在一块连续的内存空间中
- 数组名 就是第一个元素的地址
#include<stdio.h>
#include <stdlib.h>
main(){
int iarray[] ={1,2,3};
printf("iarray第一个元素的值%d\n",iarray[0]);
printf("iarray第二个元素的值%d\n",iarray[1]);
printf("iarray第三个元素的值%d\n",iarray[2]);
printf("iarray第一个元素的地址%#x\n",&iarray[0]);
printf("iarray第二个元素的地址%#x\n",&iarray[1]);
printf("iarray第三个元素的地址%#x\n",&iarray[2]);
printf("iarray数组名的值%#x\n",iarray) ;
char carray[]={‘c‘,‘d‘,‘e‘};
printf("carray第一个元素的值%c\n",carray[0]);
printf("carray第二个元素的值%c\n",carray[1]);
printf("carray第三个元素的值%c\n",carray[2]);
printf("carray第一个元素的地址%#x\n",&carray[0]);
printf("carray第二个元素的地址%#x\n",&carray[1]);
printf("carray第三个元素的地址%#x\n",&carray[2]);
printf("carray数组名的值%#x\n",carray) ;
system("pause");
}
遍历数组 ( **** )
#include<stdio.h>
#include <stdlib.h>
//输出数组中的每一个元素
void printArray(int iarray [],int length){
// 不允许在for循环中声明变量
int i=0;
for(;i<length;i++){
printf("数组中的第%d个元素的值%d\n",i,iarray[i]);
}
}
// 因为数组名 就是第一个元素的地址 所以可以用指针变量接受数组名
// 获得数组的每个元素的值 *array 获得第一个元素的值 在地址的基础上 +偏移量(内部乘以4了) 可以获取每个元素的值
void printArray2(int * array,int length){
// 不允许在for循环中声明变量
int i=0;
for(;i<length;i++){
printf("数组中的第%d个元素的值%d\n",i,*(array+i));//+i 代表就是偏移量 如果是int* 指针默认偏移4
}
}
main(){
int iarray[] ={1,2,3};
printArray2(iarray,3);
system("pause");
}
指针的长度
#include<stdio.h>
#include <stdlib.h>
main(){
printf("int* 类型的长度%d\n",sizeof(int*)); //4
printf("short* 类型的长度%d\n",sizeof(short*)); //4
printf("double* 类型的长度%d\n",sizeof(double*)); //4
printf("float* 类型的长度%d\n",sizeof(float*)); //4
printf("char* 类型的长度%d\n",sizeof(char*)); //4
// 一般 指针的长度全部都是 4 取决于编译器 64位 8
// 就是因为每个指针的默认偏移量是不一样的 int* 默认偏移 4个字节
// char* 1个
system("pause");
}
内存结构
Java
C语言内存结构
静态内存 ( ** )
系统分配的,在栈内存申请空间, 连续的内存空间 运行效率非常高, 自动回收内存
#include<stdio.h>
#include <stdlib.h>
void method1(int** q){
int i = 3;
*q = &i;
printf("i的地址%#x\n",&i);
}
main(){
// 主函数想要获取子函数i变量的地址
int* p; // 定义了指针变量 用来接受子函数变量的地址
//如果子函数想要修改主函数变量的值 必须获取到主函数变量的地址
method1(&p);
printf("p的值为%#x\n",p);
printf("*p的值是%d\n",*p);
system("pause");
}
动态内存 ( ***** )
程序员手动申请的, 在堆内存中开辟空间不一定是连续,,运行效率 略慢,容易产生碎片 需要手动回收
#include<stdio.h>
#include <stdlib.h>
main(){
//int i=3;
int* p;
p = (int*)malloc(4);
*p = 3;
printf("p的值%#x\n",p);
printf("*p的值为%d\n",*p);
free(p);// 回收内存
printf("*p的值为%d\n",*p);
system("pause");
}
#include<stdio.h>
#include <stdlib.h>
typedef int* I;
void method1(I* q){
int* i;
i = (int*)malloc(4);
*i=3;
*q=i;
printf("i的地址%#x\n",&i);
// free(i); // 回收内存, 参数申请内存的返回值
}
main(){
// 主函数想要获取子函数i变量的地址
int* p; // 定义了指针变量 用来接受子函数变量的地址
//如果子函数想要修改主函数变量的值 必须获取到主函数变量的地址
method1(&p);
printf("p的值为%#x\n",p);
printf("*p的值是%d\n",*p);
system("pause");
}
动态申请内存的灵活性
// StringBuilder
// Arraylist 10 15
main(){
// 动态录入数组
// 先录入数组的长度
int len;
printf("请录入数组的长度\n");
scanf("%d",&len);
int* iarray =malloc(sizeof(int)*len); //12
int i;
for(i=0;i<len;i++){
printf("录入第%d个元素的值\n",i) ;
scanf("%d",iarray+i);
}
printArray2(iarray,len);
int length;//扩展的长度
printf("请录入要扩展数组的长度\n");
scanf("%d",&length);
// 参数1 代表之前申请内存的地址 参数2 重新多大的空间
iarray =realloc(iarray,sizeof(int)*(length+len));// 重新动态申请内存 扩展之前的内存
for(i=len;i<len+length;i++){
printf("录入第%d个元素的值\n",i) ;
scanf("%d",iarray+i);
}
printArray2(iarray,len+length);
printf("录入完成\n");
system("pause");
}
Typedef ( **** )
给已知变量 起别名
#include<stdio.h>
#include<stdlib.h>
typedef int I; // 给int类型变量 起了别名 叫做I
main(){
I i=4;
printf("i的值%d\n",i);
system("pause");
}
指针表示字符串 ( ********** )
#include<stdio.h>
#include <stdlib.h>
main(){
char cstr1[]={‘h‘,‘e‘,‘l‘,‘l‘,‘o‘,‘\0‘};
printf("%s\n",cstr1);
char* cstr2="hello";//<=> char cstr1[]={‘h‘,‘e‘,‘l‘,‘l‘,‘o‘,‘\0‘};
printf("%s\n",cstr2);
system("pause");
}
函数的指针
#include<stdio.h>
#include <stdlib.h>
int jianfa(int x,int y){
return x - y;
}
int add(int x,int y){
return x + y;
}
main(){
// 1.定义
int (*pf)(int x, int y); // 定义了函数的指针 变量名 pf 标示 函数返回值 int类型 参数 两个int类型
//2.赋值
pf = add;
//3.引用
int result= pf(3,5);
printf("result的值%d\n",result);
system("pause");
}
结构体 ( **** )
#include<stdio.h>
#include <stdlib.h>
// 声明了结构体 三个属性 age score sex
struct Student
{
int age; //4
float score; //4
char sex; //1 2 4 8
double d; //8
}
main(){
// 给结构体赋值 struct Student 标示student 的结构体类型 变量名 st
struct Student st={80,55.6f,‘F‘ };
printf("年龄%d\n",st.age);
printf("分数%f\n",st.score);
printf("结构体的长度%d\n",sizeof(struct Student));
system("pause");
}
联合体 ( ** )
#include<stdio.h>
main()
{
struct date { int year, month, day; }today;
union { long i; int k; char ii; } mix; // 所有的元素 共享一块内存空间
printf("date:%d\n",sizeof(struct date));// 12
printf("mix:%d\n",sizeof(mix)); //4
mix.k = 5;
printf("mix.i的值%d\n",mix.i);
system("pause");
}
枚举 ( ** )
#include <stdio.h>
// 声明一个枚举
enum WeekDay{
Monday=0,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
};
int main(void){
//int day;
// 声明了枚举
enum WeekDay day = Sunday;
printf("%d\n",day);
system("pause");
return 0;
}
来自为知笔记(Wiz)
C语言基础
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。