自学c语言
C 语言是一种通用的、面向过程式的计算机程序设计语言。
当前最新的 C 语言标准为 C18
前期准备
C 编译器 写在源文件中的源代码是人类可读的源。它需要"编译",转为机器语言,这样 CPU 可以按给定指令执行程序。(.c-->.exe)
下载Dev-C++ 图标长这样哦别下载错了
编写代码
1 #include <stdio.h>
2 int main(){
3 printf("Hello World!");
4 //system("pause"); //暂停程序 不会一闪而过
5 return 0;
6 }
保存为 hello.c 文件
进入代码目录
win+r cmd 打开命令提示符 cd到程序目录执行编译 gcc hello.c 会生成hello.exe 文件
想用vs code开发C语言点击这里
数据类型
1 基本类型:
它们是算术类型,包括两种类型:整数类型和浮点类型。
2 枚举类型:
它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。
3 void 类型:
类型说明符 void 表明没有可用的值。
4 派生类型:
它们包括:指针类型、数组类型、结构类型、共用体类型和函数类型。
存储类
存储类定义 C 程序中变量/函数的可用范围和生命周期。说明符应放置类型之前
1.auto
局部变量的默认存储类, 规定变量只能在函数内部使用
2.register
定义存储在cpu寄存器中而不是 RAM(内存) 中的局部变量
3.static
局部变量时进入和离开作用域不会进行创建和销毁
全局变量时会使变量的作用域限制在声明它的文件内
4.extern
在一个文件中声明一个全局变量或函数
#include <stdio.h>
// 函数外定义变量 x 和 y
int x;
int y;
int add(){
// 函数内声明变量 x 和 y 为外部变量
extern int x;
extern int y;
// 给外部变量(全局变量)x 和 y 赋值
x = 4;
y = 2;
return x+y;
}
int main()
{
int result;
result = add();
//文件编码UTF8时中文乱码 应设为GBK
printf("result 为:%d=%d+%d",result,x,y);
return 0;
}
运算符
7个 算术运算符 关系运算 符逻辑运算 符位运算符 赋值运算符 杂项运算符
#include <stdio.h>
//不用第三个变量 A^B,异或交换值
// 这种利用位运算的交换方法只适用于整型变量,不能用于浮点型变量
int main()
{
int A = 60;//二进制 0011 1100
int B = 13;//二进制 0000 1101
A = A^B;//A=0011 0001
B = A^B;//B=0011 1100
A = A^B;//A=0000 1101
// A^=B^=A^=B; //简写
printf("原A=60 B=13,现A=%d,B=%d",A,B);
return 0;
}
enum(枚举)
一种基本数据类型 enum 枚举名 {枚举元素1,枚举元素2,……};
第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。
可以把第一个枚举成员的值定义为 1,第二个就为 2,以此类推
#include <stdio.h>
#include <stdlib.h>
// 枚举类型
int main()
{
enum Colors { red=1, blue, green };
enum Colors color;
printf("%d是红色,%d是蓝色,%d是绿色,请输入数字选择喜欢的颜色",red,blue,green);
scanf("%u",&color);
switch(color){
case red:
printf("你喜欢红色\n");
break;
case blue:
printf("你喜欢蓝色\n");
break;
case green:
printf("你喜欢绿色\n");
break;
default:
printf("没有你喜欢的颜色\n");
}
system("pause");
}
C指针
指针指向内存地址的变量,指针变量存放的是普通变量的内存地址
int var = 20; /* 实际变量的声明 */
int *ip; /* 指针变量的声明 */
ip = &var; /* 在指针变量中存储 var 的地址 */
*和&都是一元运算符
&var 返回的是变量var在内存中的地址
*ip 返回的是指向的变量var(20)的值
普通指针和数组指针:
#include <stdio.h>
// 指针 &a=获取变量地址 *a=指针变量
int main()
{
int var = 12;
int *ip = NULL; ip = &var; printf("var 变量地址:%p \n",&var);
printf("ip 变量存储的地址:%p \n",ip);
printf("ip 变量地址:%p \n",&ip);
printf("*ip 变量的值:%d \n",*ip); system("pause"); // int var = {
// 地址:000000000062FE14
// 值:12
// }
// &var = var地址 // int *ip = {
// 值:NULL
// 地址:000000000062FE10
// } // ip = &var
// *ip = var值 = 12
// ip = &var = var地址 //指针与数组
const int MAX = 3; int arr[] = {10,100,200};
int i,*ptr[MAX];
for(i=0;i<MAX;i++){
ptr[i] = &arr[i];
}
for(i=0;i<MAX;i++){
printf("var[%d] 地址:%p || %p,值:%d \n",i,ptr[i],&arr[i],*ptr[i]);
} system("pause"); return 0;
}
函数指针:
#include <stdio.h>
// 函数指针
int max(int x,int y){
return x>y?x:y;
}
int main()
{
int (*p)(int,int) = &max; //&可以忽略
int a,b,c,d;
printf("请输入3个数字:");
scanf("%d %d %d",&a,&b,&c);
d = p(p(a,b),c);
printf("最大数为:%d \n",d); system("pause");
}
字符串
C 语言中,字符串实际上是使用空字符 \0 结尾的一维字符数组。\0 是用于标记字符串的结束
#include <stdio.h>
#include <string.h>
// 字符串
int main()
{
char arr[6] = {'h','e','l','l','o','\0'};
printf("%s \n",arr); char str[] = "hello";
printf("%s \n",str); char str1[] = "字符串1",str2[] = "字符串2",str3[5]; // 操作字符串的函数 需要引入<string.h>标准库
strcpy(str3,str1);//将str1复制到str3
printf("str3=%s \n",str3); strcat(str3,str2);//将字符串str2链接到str3末尾
printf("str3=%s \n",str3); int len = strlen(str3);//返回str3的长度
printf("str3的长度为%d \n",len); int cmp = strcmp(str3,str1);//如果 str1,str3相同的,返回 0;str1<str3 返回小于 0;str1>str3 返回大于 0。
printf("cmp=%d \n",cmp); char *chr,ch='1';//ch为一个字符
// str3="字符串1字符串2"
chr = strchr(str3,ch);//返回一个指针 字符ch 第一次出现的位置
printf("chr=%s \n",chr);//返回 "1字符串2" char s[2] = "串";//汉字一般占2个字节(系统或编码方式不一样可能占3个字节)
char *ss = strstr(str3,s);//返回一个指针,指向字符串 str3字符串 s 的第一次出现的位置
printf("\'串\'出现在str3的位置为:%s \n",ss); system("pause");
}
结构体
用struct定义,自定义数据类型用来存储不同类型的数据成员
struct 结构名 {
数据类型1;
数据类型2;
...
} 变量1,变量2 ... ;
结构体变量的初始化,访问结构成员,结构作为函数参数,指向结构的指针 例子:
#include <stdio.h>
#include <string.h>
// 结构体
struct Books//生成结构体Books
{
char title[50];
char author[50];
char subject[50];
int book_id;
} book;//声明结构变量book void printBook(struct Books book);
void setBook(struct Books *b,char title[],char author[],char subject[],int book_id);
int main()
{
//初始化book变量
strcpy(book.title,"百科全书");
strcpy(book.author,"小明");
strcpy(book.subject,"啥东西都有");
book.book_id = 1; struct Books book1;//声明结构变量 book1 setBook(&book1,"十万个为啥","小红","啥东西都有解释",2); printBook(book);
printf("\n");
printBook(book1); system("pause");
} //通过指向结构变量的指针 "->"访问并初始化结构变量
void setBook(struct Books *b,char title[],char author[],char subject[],int book_id)
{
strcpy(b->title,title);
strcpy(b->author,author);
strcpy(b->subject,subject);
b->book_id = book_id;
} //结构作为参数
void printBook(struct Books book)
{
printf("标题:%s \n",book.title);//book.title 访问结构成员
printf("作者:%s \n",book.author);
printf("主题:%s \n",book.subject);
printf("ID:%d \n",book.book_id);
}
共用体
可以在相同的内存位置定义个带有多成员的共用体,只能有一个成员带有值
union 共用体名 {
数据类型1;
数据类型2;
...
} 变量1,变量2 ... ;
使用例子:
#include <stdio.h>
#include <string.h> //共用体
int main()
{
// 声明共用体
union Data{
int i;
float f;
char c[10];
}; // 定义共用体 变量
union Data data; // 初始化共用体 数据成员
data.i = 123;
printf("i:%d \n",data.i);//正常输出 123 data.f = 20.3;
printf("f:%f \n",data.f);//正常输出 20.299999 strcpy(data.c,"1234567890");
printf("c[10]:%s \n",data.c);//正常输出1234567890 // 访问共用体数据成员
printf("\ni:%d \n",data.i);//i内存位置被c[10]替换输出数据有问题 875770417
printf("f:%f \n",data.f);//f内存位置被c[10]替换输出数据有问题 0.000000
printf("c[10]:%s \n",data.c);//内存位置被替换为 正常输出1234567890 system("pause");
}
位域
1000 1000 这是8位(bit) = 1字节(byte/B)
有些信息存储时,不需要占一个完整的字节(8位),而只需占几个或1个二进制位(如:0000 0001 只需要最后1位)
所以c语言提供了一种数据结构,称为"位域"或"位段,可以设置变量用多少位
struct 位域结构名
{
//type 只能为int(整型),unsigned int(无符号整型),signed int(有符号整型) 三种类型
type [member_name] : width ;
type [member_name] : width ;
...
};
这种结构在内存中占8个字节
但是我们a和b可能只存储 0或1 只需要1位,多余的空间就会浪费。 所以就需要用到位域
使用位域后,这个结构体就占用4字节(32位)。每个变量占1位 ,还剩余30位,可以分配给剩余结构体中变量
#include <stdio.h> // 位域
int main()
{
// unsigned int类型默认是2字节或4字节
struct
{
unsigned int a:1;
unsigned int b:1;
} status;
struct
{
unsigned int a;
unsigned int b;
} status1; printf("status size:%dB \n",sizeof(status));//status size:4B
printf("status1 size:%dB \n",sizeof(status1));//status size:8B // status.a = 2;//因为a只分配了1位 2等于二进制0010 所以会报错
status.a = 1;//1等于二进制0001
printf("status.a:%d \n",status.a); system("pause");
}
typedef 和 #define
typedef:为类型取一个新的名字
#define:为各种数据类型定义别名
不同点
- typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。
- typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。
#include <stdio.h>
// typedef 关键字为类型取一个新的名字
int main()
{
typedef unsigned int BYTE;//定义unsigned int别名为 BYTE
BYTE A;
unsigned int a; #define zx int //定义int别名为zx
#define PI 3.14 //定义常量
zx b;
A = 2;
a = A;
b = a;
printf("%d == %d \n",A,a);
printf("%d,PI=%f\n",b,PI);
system("pause");
}
输入输出
C 语言把所有的设备都当作文件。所以设备(比如显示器)被处理的方式与文件相同。
#include <stdio.h> // 输入输出
int main()
{
int a;
char s[50]; // printf("Enter a value:");
// scanf("%s",&s);//输入 从标准输入流 stdin 读取输入
// printf("value = %s \n",s);//输出 写入到标准输出流 stdout printf("Enter a char:");
a = getchar();//屏幕读取下一个可用的字符,并把它返回为一个整数
printf("you entered char:\n");
putchar(a);//把字符输出到屏幕上,并返回相同的字符。
printf("\n"); // char str[100];
// printf("Enter a string: \n");
// gets(str);//从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF
// printf( "\nYou entered: ");
// puts(str);//字符串 s 和一个尾随的换行符写入到 stdout system("pause");
}
文件读写
不管是文本文件还是二进制文件,都是代表了一系列的字节。
打开文件 FILE *fopen( const char * filename, const char * mode );
filename 是字符串,文件名, mode 是下列值中的一个
r | 打开一个已有的文本文件,允许读取文件。 |
w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。 |
a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
r+ | 打开一个文本文件,允许读写文件。 |
w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
处理二进制文件:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
#include <stdio.h> //文件的读写
int main()
{
FILE *fp = NULL; // 写入文件
fp = fopen("./13.txt","w");// "w" 打开一个文本文件,允许写入文件。如果文件不存在会创建一个新文件
fputc(2,fp); //把一个字符写入到流中
fprintf(fp,"这是 创建的文件\n"); //把一个字符串写入到文件中
fputs("这是 fputs 输入的内容\n",fp); //把字符串 s 写入到 fp 所指向的输出流中 成功返回一个非负值,发生错误,返回 EOF
fclose(fp);//关闭文件 char buff[255]; // 读取文件
fp = fopen("./13.txt","r");//打开一个已有的文本文件,允许读取文件
char c = fgetc((FILE *)fp);//从 fp 所指向的输入文件中读取一个字符
printf("0:%d \n",c); fscanf(fp,"%s",buff);//读取字符串,但是在遇到第一个空格和换行符时,它会停止读取
printf("1:%s \n",buff); fgets(buff,255,(FILE *)fp);//从 fp 所指向的输入流中读取 n - 1 个字符
printf("2:%s \n",buff); fgets(buff,255,(FILE *)fp);
printf("3:%s \n",buff); // 0:2
// 1:这是
// 2: 创建的文件 // 3:这是 fputs 输入的内容 fclose(fp); return 0;
}
预处理器
相当于文本替换工具,会在编译器实际编译之前执行
14.c
#include <stdio.h> // 预处理器
#include "14.h" //包含一个源代码文件
int main()
{
//定义宏
#define PI 3.14 //把所有 PI 替换成3.14
#define uInt unsigned int //把所有 uInt 替换成 unsigned int
uInt a = 222;
#undef PI //取消已定义的宏
#define PI 3.1415926 //重新定义PI
printf("%f,%d \n",PI,a); myFun(); #ifndef MESSAGE //如果宏没有定义,则返回真
#define MESSAGE "success"
#endif
printf("MESSAGE = %s \n",MESSAGE); return 0;
}
void myFun()
{
printf("This is 14.h a=%d,arr=%s \n",a,arr);
}
14.h
int a = 4;
char arr[] = "hello word";
void myFun();
头文件
头文件是扩展名为 .h 的文件,包含了函数声明,宏定义,变量。被多个源文件中引用共享。有两种类型的头文件:程序员编写的,编译器自带。
#include <file.h>
#include "file.h"
强制类型转换
强制类型转换是把变量从一种类型转换为另一种数据类型
#include <stdio.h> // 强制类型转换
int main()
{
int a = 6;
char b = 'b';
float c = a + b;//a 强制转换为 6.000000 b 强制转换为 98('b'的ASCII=98)
printf("a=%d+b=%c,c=%f \n",a,b,c);
system("pause");
}
内存管理
C分配和管理函数。这些函数在 <stdlib.h>头文件
void *calloc(int num, int size);//分配了 num*size 个字节长度的内存,每个字节值都初始化为0 void free(void *address);//释放 address 所指动态分配的内存空间 void *malloc(int num);//堆区分配指定大小的内存空间,不会初始化值 void *realloc(void *address, int newsize);//内存扩展到 newsize
使用malloc分配内存
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int main()
{
char name[100];
char *desc; strcpy(name,"weilian tom"); desc = (char *)malloc(200 * sizeof(char));//动态分配内存 它的值不会初始化
printf("%p \n",desc); if(desc == NULL){
fprintf(stderr,"Error - unable to allocate required memory\n");
}else{
strcpy(desc,"weilian tom is a famous professional clown actor \n");
}
// free(desc);//释放内存
printf("name:%s\ndesc:%s \n",name,desc); system("pause"); }
命令行参数
执行程序时,在命令行传值给程序
传入的参数是由main函数处理的,argc是参数个数 argv是参数列表
#include <stdio.h> // 命令行参数
int main(int argc, char *argv[])
{
printf("有%d个参数 \n",argc);
int i;
for(i=0;i<argc;i++)
{
printf("第%d个参数是:%s \n",i+1,argv[i]);
}
}
执行程序后 第一个参数总是程序名
时间格式化和定时器函数
#include <stdio.h>
#include <time.h> // 标准库 time.h
void delayed(void (*fun)());
void parseTime();
int main()
{
//time_t这是一个适合存储日历时间类型
time_t curtime;//声明time_t格式变量
printf("%d",curtime); time(&curtime);//计算当前日历时间,并把它编码成 time_t 格式 printf("%s",ctime(&curtime));//ctime 返回表示当地时间的字符串 delayed(&parseTime); return 0;
} // 获取当前时间并格式化
void parseTime(){
time_t ct;
time(&ct);
// 格式化时间
struct tm *nowTime = localtime(&ct);// 返回本地时区的值来填充 tm 结构体 //年tm_year 月tm_mon 日tm_mday 时tm_hour 分tm_min 秒tm_sec
printf("%d-%d-%d %d:%d:%d \n",nowTime->tm_year+1900,nowTime->tm_mon+1,nowTime->tm_mday,nowTime->tm_hour,nowTime->tm_min,nowTime->tm_sec);
}
// 延时函数
void delayed(void (*fun)()){
while (1)
{
static int t1,t2;
if(t2-t1 > 1000){
fun();
t1 = t2;
}
t2 = clock();//返回程序执行起到现在使用的时间
}
}
搜索
复制
自学c语言的更多相关文章
- 关于自学C语言开始时应该注意的问题分享—未完待续......
---恢复内容开始--- 自学C语言编程总结 第1章C语言概述 1. 如果用户将主函数的返回值类型定义为了void,则不需要返回任何值: 2. C语言的基本结构包括主函数和程序体两部分 ...
- 先定一个小目标:10天自学C语言编程,教你如何改变一生
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- 关于自学C语言这件事
说在前面 为什么会写下这篇文章?本人也并不是什么大神,但是也自学了很久,从一个小白开始自学,期间走过很多弯路,掉过许多坑.一路跌跌撞撞下来,算是有了点收获,有了点感想,将它们记录下来,希望能帮助新入坑 ...
- 《自学C语言》初级教程 - 目录
我现在打算出一个C语言学习教程,目的是为了让初学者能够很容易和更深刻地理解C语言. 你可能有这样的疑问,网上不是有很多的初级教程吗,我需要这个吗?我的回答是:网上的C语言教程讲得不够全面,而且许多的初 ...
- 《自学C语言》第一章:C语言简介
这一章主要介绍什么是C语言,以及它的产生.发展历史.如其中所说的计算机术语有不懂的请百度,例如什么是强类型,什么是高级语言. 1.C语言是什么? 答:C语言是一门通用计算机编程语言,应用广泛.C语言的 ...
- 自学SQL语言的例子(使用MySQL实现)
SQL语言作为一种数据库管理的标准语言有着极为广泛的应用场景,菜鸟入门选用的数据库软件是轻量级的免费(这个极为重要)的MySQL,下载链接如下:http://www.mysql.com/downloa ...
- 2018.08.31 19:41 自学go语言
有的人是从最基础的开始学,而我却是从最简单开始学,学着调试,学着编程,其实我也是编程小白,好多的不懂,我不明白很多都可以用云完成了,为什么还要继续自己编程,不明白,但是有需求吧,有需求是件好事情,说明 ...
- (转)如何学好C语言,一个成功人士的心得!
zidier111发表于 2013-1-26 08:59:05 今 天,我能够自称是一个混IT的人,并能以此谋生,将来大家能一次谋生,都要感谢两个人:克劳德.香农和约翰.冯.诺依曼,是他们发现了所 ...
- 怎样学好C语言,一个成功人士的心得!
今天,我能够自称是一个混IT的人,并能以此谋生,将来大家能一次谋生,都要感谢两个人:克劳德.香农和约翰.冯.诺依曼,是他们发现了全部的数字化信息,不论是一段程序,一封email,一部电影都是用一连串的 ...
随机推荐
- JavaScript操作select下拉框选项移动
运行结果: 源代码: 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta char ...
- BootstrapBlazor实战 Chart 图表使用(1)
BootstrapBlazor组件 Chart 图表介绍 通过给定数据,绘画各种图表的组件 本文主要介绍三种图表使用:折线图,柱状图,饼图 1.新建工程 新建工程b06chart,使用 nuget.o ...
- 使用docker安装centos6.10镜像并安装新版gcc
使用docker安装centos6.10镜像并安装新版gcc 环境:Linux Ubuntu 16.04.7 LTS 目录 使用docker安装centos6.10镜像并安装新版gcc 使用docke ...
- js知识梳理6:关于函数的要点梳理(2)(作用域链和闭包)
写在前面 注:这个系列是本人对js知识的一些梳理,其中不少内容来自书籍:Javascript高级程序设计第三版和JavaScript权威指南第六版,感谢它们的作者和译者.有发现什么问题的,欢迎留言指出 ...
- Mybatis多表查询出现null字段
写在前面 今天使用mybatis实现多表查询,记录一下其中遇到的坑 mybatis多表查询简介 mybatis多表查询主要有两个方式,通俗易懂的来说就是一个是查询少量属性(association),一 ...
- Hash-题解-方法
有效的字母异位词 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 示例 1: 输入: s = "anagram", t = "nagar ...
- 解决关于ARM_MATH数学库宏定义的报错
昨天在建立新工程的时候发现加入含有ARM_MATH库的时候出现了宏定义报错. #error directive:"Define according the used Cortex core ...
- os、sys、json、subprocess模块
今日内容概要 1.os模块 2.sys模块 3.json模块 4.subprocess模块 今日内容详细 os模块 """该模块主要是跟操作系统打交道"&quo ...
- 【分享汇总】25个主题分享,360°领略OpenHarmony最新技术版图
2021年10月,开放原子开源基金会旗下开源项目 OpenAtom OpenHarmony (以下简称"OpenHarmony") 应邀参加华为2021 HDC 开发者大会,并组织 ...
- 【面试普通人VS高手系列】Dubbo的服务请求失败怎么处理?
今天分享的面试题,几乎是90%以上的互联网公司都会问到的问题. "Dubbo的服务请求失败怎么处理"? 对于这个问题,我们来看一下普通人和高手的回答. 普通人: 嗯- 我记得, D ...