C语言基础实例

本文深入探讨了C语言的基础知识,包括数据类型、输出与输入函数、指针的概念与应用,以及如何使用指针进行高效数据传递。此外,还详细介绍了C语言中的数组、动态内存分配、结构体与指针变量的关系,并通过实例展示了如何利用指针进行复杂数据结构的操作。文章旨在为C语言的学习者提供全面而深入的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

调用java代码

#include <stdio.h> #include <stdlib.h> main() { //输出 printf("Hello world !\n"); //调用java代码 system("java HelloWorld"); //调用系统cmd里面的命令,pause 暂停执行 system("pause"); }

基本数据类型

C的基本数据类型:char, int, float, double, signed, unsigned, long, short and void

C语言没有boolean,byte , String的数据类型一般用 int 0 ,1 表示boolean,char 表示btye类型

#include<stdio.h> int main(){ // sizeof() :获取到某种数据类型的长度 // %d 是一个占位符 printf("char占用的长度为 %d\n" , sizeof(char)); 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)); // signed 和 unsigned用来指定某个数据类型是有符号的还是无符号的 //它只能修饰int、long,而不能修饰 double float浮点双精度的类型 //java中的long占用8个字节 c语言 4个字节 system("pause"); return 0; }


输出类型的标示符

#include<stdio.h> int main(){ int i = 3555; long l = 333333; char c ='A'; float f = 3.141592; double d = 3.33333; printf("int %d\n",i); //int输出类型的标示符为%d printf("long %ld\n",l); //int输出类型的标示符为%ld printf("char %c\n",c); //... printf("float %f \n",d); //... printf("double %lf \n",d);//... printf("i的16进制 %#x\n",i); //16进制输出类型的标示符为%x system("pause"); }


输出函数

#include <stdio.h> #include <stdlib.h> main() { //输出 printf("Hello world !\n"); //调用java代码 system("java HelloWorld"); //调用系统cmd里面的命令,pause 暂停执行 system("pause"); }


输入函数

#include<stdio.h> int main(){ //定义了一个长度为10的char数组 char arr[10]; //接收字符串并放到arr数组中 scanf("%s", arr); //打印字符串 printf("字符串%s \n ", arr); system("pause"); }

什么是指针

#include<stdio.h> int main(){ int i =3 ; // 定义个一个变量 名字p ,变量的类型是int* 的类型 ;也可以写成int* p, int *p; // int* 的类型就是一个指针类型 ,指针用来表示一个地址 // p是一个变量, 这个变量里面存放的数据类型 , 必须是一个指针类型的数据( p里面的存放的数据必须是一个地址) int* p ; //&取地址符号,可以把变量的一个地址取出来 ,p里面存放的是i的地址 //变量名i 程序编译运行的系统会自动把变量名和对应的地址产生对应关系 p = &i; printf("i的地址%#X\n",&i); //* 星号操作符 , 取到某个地址里面存放的数据 printf("p所指向地址里面的数据内容是 %d\n " ,*p); // *p 和 i 是同一个东西 //改变*p的值 ,i的值也回改变 *p=88; printf("i数据内容是 %d\n " ,i); // 改变i的值 ,*p的值也回改变 i = 99; printf("改变后*p的值 %d\n " ,*p); // p 跟 i 没有关系, 修改p的值 不会影响i的值 , 修改i的值 也不会影响p的值 system("pause"); }


指针的常见错误

1. 指针p未经赋值, 不能使用 *p的数据
2. 指针类型的变量,只能存放地址类型的数据 .
3. 不同类型的指针变量,不同互相赋值

#include<stdio.h> int main(){ // p指针变量虽然被定义出来了, 没有赋初值, 里面的内容垃圾值 . int* p ; // p里面的地址不确定 // 获取一块不确定的内存地址里面的值 . printf("p所指向的值是 %d\n",*p); p = 33; //错误的 33是一个int类型 ,数据类型不同 char c ='A'; p = &c; // 错误的&c获得的是 字符的地址 , p 是一个int数据类型的地址 system("pause"); }


指针和指针变量的关系

指针就是地址,地址就是指针
地址就是内存单元的编号
指针变量是存放地址的变量
指针和指针变量是两个不同的概念
但是要注意:通常我们叙述时会把指针变量简称为指针,实际它们含义并不一样
为什么使用指针
直接访问硬件 (opengl 显卡绘图)

快速传递数据(指针表示地址)

返回一个以上的值(返回一个数组或者结构体的指针)

表示复杂的数据结构(结构体)

方便处理字符串

指针有助于理解面向对象

指针-快速传递数据

要在另外一个函数中 去更改主函数的值
1. 把要修改的变量的的地址作为参数传递到子函数里面
2. 子函数里面 要接受到 主函数传递的地址 ( 子函数的形参是一个指针类型的形参)
3. 通过使用地址对应的变量, 修改主函数里面的某个变量

#include <stdio.h> #include <stdlib.h> void swap(int i ,int j){ int temp; temp = i; i = j; j = temp; } //需要获取到两个变量的引用, 需要两个变量的地址作为形参传递过来 . void swap2(int* p ,int * q ) { int temp; temp = *p; *p = *q; *q = temp; } main() { int i = 3; int j = 5; //swap(i,j); //值传递不会互换 swap2(&i,&j); //引用传递,传递内存地址会互换 printf("i的值是%d\n",i); printf("j的值是%d\n",j); system("pause"); }

指针-返回一个以上的值
#include <stdio.h> #include <stdlib.h> // 指针参数 接受两个地址 //通过指针 让函数返回了两个值 void f1(int* p , int* q ){ *p = 8; *q = 10; } main() { int x =3 ; int y =5; f1(&x, &y); printf("x的值是 %d\n",x); printf("y的值是 %d\n",y); system("pause"); }

指针和数组的关系

一维数组名是个指针常量,它存放的是一维数组第一个元素的地址

java中定义数组可以用:int[] arr, int arr[] ,在C中只能用int arr[]

c语言不检查数组的下标 ,容易产生很危险的情况缓冲区溢出

#include <stdio.h> #include <stdlib.h> int main(){ int arr[10]={1,2,3,4,5,6,7,8}; printf("数组的第一项是 arr[0]= %d\n",arr[0]); //下边返回2293672 ,说明 c语言不检查数组的下标 printf("数组的最后一项是 arr[11]= %d\n",arr[11]); //arr是数组名,代表一个首地址 printf("arr的值 %#X\n",arr); //数组地址 0X22FF40 printf ("数组的第一个元素的arr[0]的地址 %#X\n",&arr[0]); //0X22FF40 //把指针移动到下一个位置 , 获取这个地址里面的值 ,*(arr+1) ,获取数组第二个元素 // *(arr+1) 和arr[1] 代表的是同一块内存,指向的是同一个变量 printf ("数组的第二个元素的值%d\n", *(arr+1)); system("pause"); }


确定一个c语言的数组

确定一个数组需要两个参数 1,数组的首地址 ,2. 数组的长度

#include <stdio.h> #include <stdlib.h> void printArr(int * p , int len){ int i =0 ; for(;i<len;i++) { //通过指针去获取数组里面的每一个值 // printf("arr[%d]= %d\n", i, *(p+i)) ; //通过数组下标打印数组里面的每一个值 //数组的首地址 , 可以当成数组名去使用 printf("arr[%d]= %d\n", i, p[i]) ; // *(p+i) p[i]代表的是同一块内存空间 指向的是同一个变量 } } main() { int arr[5] = { 1,2,3,4,5}; //arr存放的数组的首地址 printArr(arr ,5 ); system("pause"); }

指针的运算

#include<stdio.h> int main(){ int i = 3; int j = 5; int* p = &i; int* q = &j; // p-q; 没有逻辑意义 p 天津门牌号30 q 北京的门牌号 50 char arr[20]={'a','b','c','d'}; printf("%c" , *(arr + 1)); char* c1 = &arr[5]; char* c2 = &arr[10]; printf("c2和c1之间的距离 %d\n" ,c2-c1); // c2-c1 =5 (偏移量) system("pause"); }

指针-方便处理字符串

#include<stdio.h> int main(){ //定义了一个字符串 \0; char* str = "hello c language"; printf("%s", str); system("pause"); }

*号的三种含义

1.乘法

2.定义指针变量 int * p;//定义了一个名字叫p的变量,能够存放int数据类型的的地址

3.指针运算符,//如果p是一个已经定义好的指针变量则*p表示以p的内容为地址的变量

内存动态分配

// malloc memory allocate 内存分配 #include<stdio.h> int main(){ int i ; //栈内存中 静态的分配一个空间 4byte int* p = (int*)malloc(4); // 参数的要申请的内存空间的大小 // 在堆内存中申请一块空间 // 函数的返回值是申请的空间的首地址 // int* p = malloc(4); 在内存中申请了8byte的空间 // 4byte是静态申请,用来存放 p指针的内容 // 4byte是动态申请的, malloc申请 大小为4byte 可以存放一个int类型的数据 *p = 5; printf("*p的值是 %d \n", *p); //回收掉申请的空间 free(p); //p 参数是申请到的空间的首地址 //编译,运行没有问题 , 逻辑问题 . // p地址对应空间已经被释放掉了. printf("*p的值是 %d \n", *p); system("pause"); }


动态的创建数组

#include<stdio.h> void printArr(int* p, int len){ int i= 0; for(;i<len;i++){ printf("数组的第%d个元素的值为%d\n",i, *(p+i)); } free(p); printf ("数组的第3个元素的值为%d\n", *(p+3)); } int main(){ printf("请输入数组的大小\n"); int len; //获取键盘的输入的int的数据 scanf("%d",&len); //动态的创建大小为 4*len bytes 内存空间 int* p =(int* )malloc(sizeof(int) * len); int i=0; for(;i<len;i++){ printf("请输入数组的第%d个元素的值\n",i); scanf("%d", (p+i)); } printArr(p, len); system("pause"); }


动态改变数组的长度

在使用数组的时候,如果发现内存空间不够用了,可以用realloc函数重新分配数组的长度

#include<stdio.h> #include<malloc.h> // malloc 和 realloc 所在的头文件 int main(){ //创建一个大小为5的内存空间 int* p =(int*) malloc(5*sizeof(int)); p[0] = 1; p[1] = 2; p[2] = 3; p[3] = 4; p[4] = 5; //realloc第一个参数是数组的首地址,第二个参数是修改后的空间的大小 p = (int* )realloc(p,6*sizeof(int)); p[5] = 6; printf("%d\n", p[5]); //释放内存 free(p); system("pause"); }

多级指针

#include<stdio.h> int main(){ int i = 5; int* p = &i; //int * 可以存放 int类型的变量的地址 int** q = &p; // int** 可以存放 int* 类型变量的地址 int*** r = &q; //int *** 可以存放的是int** 类型的地址 printf("i 的值是 %d \n", ***r); system("pause"); }

函数的指针

#include<stdio.h> int add(int x, int y ){ return x+y; } int main(){ // 定义普通函数 int fp( int x, int y); // 定义一个函数的指针 int (*fp)(int x, int y); int (*fp)(int x, int y); // 函数的指针赋值 fp是一个变量 ,变量表示的是一个 函数的入口地址 fp = add ; printf("函数的首地址 %#X\n", fp); // 调用 指针函数 printf("%d\n", fp(3,5)); system("pause"); }

结构体

#include<stdio.h> struct Student { int age; //4 float score; //4 long id; //4 char sex; //1 }; int main(void) { struct Student st={80,55.6f,100010,'F'}; printf("年龄为%d\n", st.age); //查看结构体的长度 printf("student结构体的长度为 %d \n" ,sizeof(st)); // 输出的长度按理应该是13,结果却是16,结构体 编译器不同 ,他有不同的数据对齐方式 , // 导致结构体 在内存中的长度可能会有区别 . system("pause"); }

结构体的指针

#include<stdio.h> struct Student { int age; //4 float score; //4 long id; //4 char sex; }; int main(void) { struct Student st={80,55.6f,100010,'F'}; // 定义结构体的指针 struct Student* sp = &st; //-> 获取结构体里面的 某个字段 printf("学生的年龄为%d \n" , sp-> age); // sp-> age 在程序执行 (*sp).age system("pause"); }

结构体三种初始化方法

//第一种方式 struct Student { int age; float score; char sex; } //定义一个名字叫st1 的结构体 struct Student st={80,55.6f,100010,'F'}; //第二种方式 struct Student2 { int age; float score; char sex; } st2; //直接定义一个名字叫st2 的结构体 //第三种方式 struct { int age; float score; char sex; } st3 // 类似于 java的匿名内部类


枚举

#include <stdio.h> enum WeekDay { Monday = 5,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday }; int main(void) { //int day; enum WeekDay day = Sunday; printf("%d\n",day); system("pause"); return 0; }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值