C语言是一门计算机语言,用于和计算机交流。
这篇文章介绍了C语言里面的一些简单概念。
学习C语言需要了解这些名词:数据类型、变量和常量、字符串、转义字符、选择与循环、函数数组、操作符、关键字、预处理指令、指针、结构体。
下面举一个例子介绍一个简单的C语言程序:
//hello world
#include
int main()
{
printf("hello world");//打印hello word
return 0;
}
这是程序里面包括了:
//头文件
#include
3.main函数:主函数,一个项目里面必须有一个主函数,且只能有一个。
- 前面的int表示main函数的返回值是int类型的。
- 中间的内容需要用花括号括起来。
- 后面的()是函数调用操作符,在函数名后面使用。
4.return 是返回,后面的0是整形 (也可以把0换成其他整形),对应了前面的int
5.语句:C语言中有一个分号隔开的叫做语句
6.注释:
注释的内容会被编译器忽略
方式1://注释的位置
方式2:/*注释的位置*/
表示 | 数据类型 |
---|---|
char | 字符型 |
short | 短整型 |
int | 整形 |
long | 长整形 |
long long | 更长的整形 |
float | 浮点型 |
double | 双精度浮点型 |
合理使用数据类型可以节约内存
因为不同的数据类型占用的大小不一样,而这个大小我们可以通过运行C语言程序来显示出来`
#include
int main()
{
printf("%d\n",sizeof(char));//1
printf("%d\n",sizeof(short));//2
printf("%d\n",sizeof(int));//4
printf("%d\n",sizeof(long));//4
printf("%d\n",sizeof(long long));//8
printf("%d\n",sizeof(float));//4
printf("%d\n",sizeof(double));//8
return 0 ;
}
注释里面的数字代表了所输入的这几个类型的大小(即使用不同类型创建的变量所占有的内存,单位:字节)
变量分为局部变量和全局变量
创建局部变量时,最好要初赋值,可以避免了后续内容出错
1.(优先性):
#include
int b=100//在这里b为全局变量
int a=200//在这里a为全局变量
int main()
{
int a=10;//这里为局部变量
printf("%d\n",a);/*当局部变量和全局变量名字相同时,优先的
是局部变量,尽量不让他们名字相同*/
return 0;
}
2.(区域性):
#include
int main ()
{
{
int a=10
}
printf("%d\n",a);//这里无法打印,因为局部变量a只能在它所处的区域里面使用
return 0;
}
声明变量的顺序有时候很重要
# include
int main()
{
//计算两个数的和
int num1 = 0;
int num2 = 0;//这里两个零都是初赋值,换成其他的数值也行
//输入数据-使用输入函数
int sum = 0;//这里就是最前面
scanf("%d%d", &num1,& num2);
//int sum =0----C语言规定:变量要定义在当前代码块的最前面
sum = num1 + num2;
printf("sum=%d\n", sum);
return 0;
}
&是取地址符号
C语言规定:变量的定义要在当前代码块的最前面
作用域:程序设计概念,一段程序代码中所用到的名字并不总是有效的/可用的。。
而限定这个名字的可用性的代码范围就是这个名字的作用域。(哪里可以用,哪里就是它的作用域)
# include
int main()
{
{
int num=0;/*这里不能打印,
因为这里的int num=0作用域(当前代码块)限制了,
无法打印,类似于局部变量*/
}
int num = 0;
printf("num=%d\n", num);
//这里可以打印num=0,表示在这个代码块是int num =0的作用域
return 0;
}
# include
int main()
{
printf("num=%d\n", num);
{
int num=0;//这里可以打印,以为这处的代码块被外面代码块包含
}
return 0;
}
全局变量的作用域是整个工程
extern声明:
可以使用另一个源文件里面声明过的量
在大括号外面也可以用,项目外面也也可以用
生命周期
局部变量:进入它的作用域 生命周期开始,出去则结束
全局变量的生命周期在整个程序
比如:
100;
3.14;
‘a’;
“a”;
常变量,有常属性,但本质上还是个变量,在使用常量时,没有办法使用,
#include
int main()
{
//const---常属性
const int num = 4;//num不能更改了
printf("%d\n", num);
//num = 8;//这里的num无法更改,会报:无法修改的左值
//printf("%d\n", num);
return 0;
}
#include
#define MAX 10//定义的标识符常量
int main ()
{
int arr[MAX] = {
0 };
printf("%d\n", MAX);//打印出10
return 0;
}
#include
enum SEX
{
MALE,
FEMALE,
SECRET
};
int main()
{
//枚举关键字 enum
enum SEX s = FEMALE;//这里s是枚举里面的变量
printf("%d\n", MALE);//0
printf("%d\n", FEMALE);//1
printf("%d\n", SECRET);//2
return 0;
}
“hello”
字符串是一系列被视为一个处理单元的字符,我们可以用数组来储存字符串
符
字符串和字符不同
双引号引起来的单个字符也属于字符串
"hello bit"这是一个字符串
“”----空字符串
注:C语言中字符串是以空字符结尾的一系列字,(字符串的结束标志是一个\0的转义字符)在计算字符串长度的时候\0是标志。不算作字符串内容。
char arr1[]="abc";
//"abc"='a''b''c''\0' '\0'是字符串的结束标志,不算字符串的内容
char arr2[]={
'a','b','c'};
//就是'a''b''c'没有结束标志,会出现随机值加\0与0都一样
转义字符 | 注释 |
---|---|
? | 连续书写多个问号时,防止被解析成三字母词 |
\ | 用于表示一个斜杠 |
\a | 警告字符 |
\b | 退格 |
\f | 进纸 |
\v | 垂直制表符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\ddd | 八进制 |
\xdd | 十六进制 |
关于八进制与十六进制:
#include
#include
int main ()
{
printf("%s\n",strlen("c:\test\32\test.c"))//13,其中\32是一个字符。
return 0;
}//这里用到了strlen函数,这个函数在string头文件中,所以要在前面声明
//strlen函数是用来计算字符串长度的函数
:
分支语句:if、switch
循环语句while、for 、do while
对于条件判断很重要,而C语言如何表示真假的呢?
//C语言中用0 表示假,非零表示真
//真-->假:0
//假-->真:1
语法结构:if(expression)
statement;
双分支语句:if(expression)
statement;
else
statement;
#include
int main ()
{
int age =20;
if(age>=18)
printf("成年\n");
else
printf("未成年\n")
printf("不可以谈恋爱");/*这一行不被包括在else里面,
如果需要一起打印出来,需要组成一个代码块用{}将其包含起来*/
return 0;
}
多分支语句
#include
int main()
{
int age =10;
if(age<18)
prinrt("未成年\n");
else if(age>=18&&age< 28)//可以不用&&前面那一块,只写age<28也行
printf("hahah");
else if(age>28)//可以用这种写法
printf("wowowo");
return 0;
}
悬空else:
else与离他最近的if匹配
include<stdio.h>
int main()
{
int a = 1;
int b = 2;
if (a == 0)
if (b == 2)
printf("hehe\n");
else
printf("haha\n");//这里什么都不会打印,因为这个else与
return 0;
}
结构:
switch(整形)
{
case:
表达式;
}
#include
int main()
{
int n = 0;
scanf_s("%d", &n);
switch (n)
{
case 1:
printf("星期一\n");
break;//跳出
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
default:
printf("输入错误");
break;
}
return 0;
如果没有break:不会跳出,从一个入口进去后,会按顺序依次执行,知道遇见break出去或者结束;
default:入口以外的输入,可以用来执行错误输入后的方向。
对于switch后面括号里的n:只能用来表示整形 eg:1\2\3+4…
关于switch的例题:
#include < stdio.h >
int main()
{
int n = 1;
int m = 2;
switch (n)//这里n进去
{
case 1://n等于1,从第一个入口进去
n++;
m++;
case 2://case 1 后面没有break,故继续执行case 2
n++;
case 3://case 2 后面没有break,故继续执行case 3
switch (n)//这时,n等于3
{
case 1:
n++;
case 2:
m++;
n++;//因为n等于3,不会参与前两个case
case 3://n从这个入口进去
m++;
break;//跳出
}
case 4://继续执行case 4
m++;
break;//跳出
}
printf("n=%d,m=%d", n , m );
return 0;//得到n=3,m=5
}
while(expression)
statement;
若括号里面的条件为真,则继续循环
比如:
#include
int main()
{
while (1)
printf("hehe\n")//会处于死循环,一直打印hehe
return 0 ;
}
#include
int main()
{
int a = 1;
while (a <= 10)
{
if ( a == 5)
//continue:可以跳过本次循环后面的代码,这直接进行判断while条件
//break;
//在while循环中break可以永久终止循环
printf("%d\n", a);
a++;
}
return 0;
#include
int main()
{
//int ch = getchar();
//printf("%c\n", ch);
//putchar(ch);
//return 0;//输入一个字符,打印一个字符
int ch = 0;//getchar()不会忽略空格
while ((ch = getchar()) != EOF)//输入一个字符,打印一个字符
putchar(ch);
}
for、do while循环后面介绍
C语言里面什么是函数?
C语言中把一个个分装的功能变成函数
求两个整数的和
#include
int main()
{
int num1 = 0;
int num2 = 0;
scanf("%d,%d", &num1,&num2);//格式要严格,(“”)里面是什么就怎么输入
int sum = num1 + num2;
printf("%d\n", sum);
return 0;
}
利用函数
#include
//函数声明,放在前面
int ADD(int x, int y)
{
//add是函数名,自己创作
//int x...是参数
//大括号是函数体
//int是返回类型
int z = x + y;
return z;
}
int main()
{
int num1;
int num2;
int sum;
scanf("%d %d", &num1, &num2);
sum = ADD(num1, num2);
printf("%d\n", sum);
return 0;
}
数组:一组相同类型元素的集合
形式:类型 变量名[ 数组大小] = {元素 };
注意:数组[这里不能用变量];
#include
int main()
{
//arr就是十个元素的整形数组
char ch[5] = {
'a','b','c','d','e'};
int arr1[10] = {
1,2,3,4,5,6,7,8,9,10 };
int a[100] = {
0 };//不完全初始化,其他也全为0
//数组的下标
//下标从零开始,不管里面储存了什么
//可以通过下标查到
printf("%d", arr1[2]);
int i = 0;
while (i <= 9)
{
printf("%d\t", i);
printf("%d\n", arr1[i]);
//i大于数组制定的个数时,会造成越界(非法访问),拿不到想要的内容
i = i + 1;
}
return 0;
}
(这里介绍两个比较特殊的:除、取余)
#include
int main()
{
//除法:符号: /
int a = 7 / 2;//都是整数的话,执行整数除法,不会得到小数
float m = 7.0 / 2;//3.500000两边只要有一个小数,则执行浮点数除法
printf("%d\n", a);//3
//取余:符号: %
int n = 0;
scanf("%d", &n);
int b = 7 % 2;//1
if (n % 2 == 1)
printf("n是奇数\n");
else
printf("n 是偶数\n");
}
//-----------注意:%只能用于整数,其他的话是非法操作
//移位操作符:作用于二进制位
#include
int main()
{
int a = 1;
int b = a << 1;//左移位,相当于乘以2
int c = a >> 1;//右移位,不一定相当于除以2
printf("%d\n", b);//2
printf("%d\n", c);//0
return 0 ;
}
按位与&: 有0为0 全1为1
按位或|: 有1为1 全0为0
按位异或^:相同为0,相异为1
这里的位是指二进制位
#include
int main()
{
int a = 3;
int b = 5;
int c = a & b;
printf("%d",c);//1
return 0;
//3: 00011
//5: 00101
//得到c: 00001
//赋值:=
//复合赋值:
a += 1;
a = a + 1;//这两种赋值方式效果一样,其余的运算符号复合赋值和这个方式相同
//计算变量或者类型创建变量占据内存的大小,单位是字节
#include
int main()
{
int c = 10;
printf("%d\n", sizeof(c));
printf("%d\n", sizeof(int));
return 0;
}
//~是按位取反,二进制位操作的都是内存的二进制位,对内存中的 补码进行取反
//二进制最高位是1--->负数
/*-1
原10000000000000000000000000000000001
补码:1111111111111111111111111111111
反码111111111111111111111111111111110
/*
前置++:先++,后使用
后置++;先使用,再++
*/
#include
int main()
{
int a = 1;
int b = ++a;//a=2,b=2
printf("%d\n", b);
printf("%d\n", a);
int c = a++;//c=2,a=3
printf("%d\n", c);
printf("%d\n", a);
return 0;
}
//强制类型转换
#include
int main()
{
int a = (int)3.14;
printf("%d", a);
float b = 3.14;
printf("%d",(int) b);//将浮点型转换为整形
return 0;
}
/*
关系操作符
判断相等是两个等号
逻辑与 : &&---并且
逻辑或 : ||---或者
*/
#include
int main()
{
int a = 3;
int b = 5;
int max;
scanf("%d %d", &a, &b);
if (a == 3 && b == 3)//不满足
printf("haha\n");
if (a == 3 || b == 3)//满足
printf("hehe\n");
if (a < b)
max = b;
else
max = a;
printf("%d\n", max);
return 0;
}
形式:exp1 ? exp2:exp3(可以简化if语句)
/*
exp1 ? exp2;exp3
1为真,算2;
1为假,算3;
*/
#include
int main()
{
int a = 0;
int b = 0;
int max = 0;
scanf("%d %d", &a, &b);
max = (a > b ? a : b);
printf("%d\n", max);
return 0;
}
符号: ,
#include
int main()
{
const int COUNT = 40;
const int NUMBER = 20;
int cost, ounces;
printf("ounces cost\n");
for (ounces = 1, cost = COUNT; ounces < COUNT; ounces++)
printf("%d",ounces);
return 0;
}
//这里可以同时给ounces和cost都赋值,但是有顺序
//ounces比cost先赋值
//逗号运算符对于顺序有要求:
//后面用不到的话不用要求顺序
#include
int add(int x, int y)
{
int z = x + y;
return z;
}
int main()
{
int sum;
sum = add(3, 5);//这个括号就是函数调用操作符
//add,3,5这三个是操作数--缺一不可
return 0;
}
break—“终止”,一般在循环中使用。
case—”选择“,在switch中使用。
const—“常属性”,修饰变量与指针。
continue–”继续“,用于循环。
default—“默认”,switch里面可以使用。
enum—“枚举类型”。
extern—“声明外部变量与函数”。
signed—”有符号的“
unsigned—“无符号的”
void—”空“,返回类型,修饰指针。函数参数
struct—“定义结构体”
union----“联合体”
register—”寄存器“
注意:define 与include不是关键字 他们是预处理指令
是自动的,每个局部变量都是auto修饰的
#include
int main()
{
{
int a = 0;//a会自动生成,也会自动销毁,是自动变量。前面的auto省略。
}
return 0;
}
#include
typedef unsigned int u_int;
int main()
{
unsigned int num1 =100;//
u_int num2 =200;//这两条意义相同。
return 0;
}
看起来改变的是局部变量的作用域(本质上改变了变量的存储类型)**
#include
void text()
{
int a=1;
a++;
printf("%d",a);
}
int main ()
{
int i=0;
while(i<10)
{
text();
i++;
}
return 0;
}//输出结果为2222222222,这里局部变量a在text函数里面多次生成并且销毁,每次打印出来都为2.
和下面这个作比较
#include
void text()
{
static int a=1;//这里改变了变量a的类型,a不会被多次销毁。
a++;
printf("%d",a);
}
int main ()
{
int i=0;
while(i<10)
{
text();
i++;
}
return 0;
}//输出结果为234567891011.
使得该全局变量只能在该他所在的源文件使用,不能在其他地方使用
全局变量在其他源文件可以使用,是因为它具有外部链接属性,但是被static修饰后变成了内部链接属性,其他源文件不能链接到这个静态的全局变量了
没有static修饰,函数可以被其他源文件使用
由static修饰后,其他原文件不能使用显示:报错:无法解析的外部命令
static修饰函数,使得函数只能在自己文件内部使用,不能在其他源文件使用
本质上是将函数的外部链接属性变成了内部链接属性(与修饰全局变量很相似)
define是一个预处理命令
#include
#define MAX 1000
int main()
{
printf("%d\n",MAX);
return 0;
}//打印出1000
#include
#define ADD(X,Y) X+Y
int main()
{
printf("%d\n",ADD(2,3));//打印出5
printf("%d\n",4*ADD(2,3));//打印出11------4*2+3--替换
return 0;
}
简单了解指针之前需要了解内存。
#include
int main()
{
int a = 10;
/*
创建变量a要在内存中开辟空间
a是一个整形,所以这个空间占四个字节(四个格子)
四个格子有四个地址,而第一个地址就是a的地址
*/
printf("%p\n",&a);
/*
%p是打印地址的格式
这里用到了&符号(取地址符号),
取出的就是四个空间中的第一个地址
也就是a的地址
*/
int *p = &a;
/*
p就是指针变量,用来存放地址的(这里存的a的地址);
*是在告诉我们p是指针变量;
int是表示p指向一个整形变量
*/
char ch = 'w';
char *pc = &ch;//和上面相同
我们可以通过指针变量直接操控原变量
*p = 20;
printf("%d\n",a);//20
//* 是解引用操作符-也叫做间接访问操作符
//通过p中的值,找到p所指向的对象
//*p 就是 a
return 0;
}
#include
int main()
{
printf("%d\n", sizeof(char*));
printf("%d\n", sizeof(short*));
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(float*));
printf("%d\n", sizeof(long*));
printf("%d\n", sizeof(double*));
return 0;//结果全是四
}
指针变量的大小只需要四个字节
指针变量多大取决与地址存放占多大空间
在32位环境下,指针的大小是4个字节
在64位环境下,指针的大小是8个字节
用来解释复杂对象
复杂对象:
人:名字,年龄。性别,
书:书名,作者,出版社,定价,书号
#include
struct stu//这里创建结构体
{
char name[20];
int age;
char sex[10];//这三个是结构体成员
};//这里数组空间大小必须明确指定
int main()
{
//创建变量,并且初始化
//结构变量 可以修改
struct stu zhangsan = {
"张三",30, "男" };
struct stu lisi = {
"李四",20,"保密" };//双引号是用来引字符串的
struct stu* pl = &lisi;//pl是指针
//字符串用"",字符用''
//打印结构体的数据
printf("%s %d %s\n", zhangsan.name, zhangsan.age, zhangsan.sex);
printf("%s %d %s\n", (*pl).name, (*pl).age, (*pl).sex);
printf("%s %d %s\n", pl->name,pl->age,pl->sex);//简洁一些
return 0;
}
1.— 点操作符( . ):
结构体变量.结构体成员
2.— 箭头操作符 ( -> ):
结构体指针->结构体成员