C语言-C语言概述

创建一个后缀名为.c的源文件,在此文件中写第一个C语言程序

第一个C语言程序

#include
int main(void)
{
	printf("hello world");
	getchar();
	return 0;
}

#include是C语言的预处理指令,用于引入等系统头文件

getchar();库函数,程序需要等待键盘输入回车键才结束

数据类型与变量

  1. 字面量

字面量或者说常量,指的是有固定的值的数据。在程序中,常量只能被引用,而不能被更改

a. 整型

整型,或者说整数类型。在printf()函数中,不能直接输出,需要使用%d来占位替换输出

整型有long,int,short,char

%d表示“十进制整数”形式

#include
int main(void)
{
	printf("money is %d", 300);
	getchar();
}

b. 浮点数

浮点数,或者说小数类型。在printf()函数中,不能直接输出,需要使用%f来占位替换输出

默认情况下,输出浮点数保留小数点后6位数字。%.2f,保留两位小数

#include
int main(void)
{
	printf("money is %f", 3.1);
	printf("money is %f", -3.123);
	getchar();
} 

浮点数有:单精度浮点型float,双精度浮点型double。float赋值字面量时,需要以f结尾

输出double要用%lf,也可以用%f,但是不推荐

#include
int main(void)
{
    float f = 3.14f;
    double d = 3.14;
	printf("money is %f", f);
	printf("money is %lf", d);
	getchar();
    return 0;
} 

VS2012中执行的是C89标准,变量必须在所有其他代码之前声明

c. 字符型

单引号括起来的字符被称为字符型,注意只能是单个字符被括起来

在printf()函数中,不能直接输出,需要使用%c来占位替换输出

转义字符。比如\n表示换行符,\”代表双引号字符本身,此时不再具有特殊的意义

#include
int main(void)
{
	printf("mon\ney");//输出mon (换行) ney
	printf("mon\\ney");//输出mon\\ney
	getchar();
    return 0;
} 

d. 字符串

双引号括起来的若干字符被称为字符串,可以直接在printf()函数中输出

字符串的占位符用%s来代替

在C语言中,是没有字符串类型的,字符串本质上是由单个的字符构成

printf()函数中可以使用多个占位符,只要和参数的类型、个数能够对的上即可

  1. 变量

一个合法的变量由3部分组成,变量类型,变量名,变量值

变量必须定义才能使用;所有变量要声明在方法的最开始;变量必须初始化之后才能使用;变量不能重名

在c语言中,变量定义的位置可以分为3种

  1. 在函数内定义(局部变量)
  2. 在函数内的语句块中定义(局部变量)。语句块中可以定义变量,但必须定义在其他语句之前
  3. 在函数外部定义(全局变量)

a. 标识符

对变量,函数,数组等命名的字符序列被称为标识符。标识符有以下规定:只能由英文字母,数字,下划线组成;首字符必须是字母或者下划线;大小写敏感;不能全部是关键字

b. 关键字

C语言中,具有特殊用途的单词被称为关键字。比如int,return,break,if,void等

c. 注释

//单行注释
/* */多行注释

变量的赋值方式

每行定义与赋值

int i = 1;
int j = 2;
int k = 3;

一行定义

int i = 1, j = 2, int k;
k = 3;

运算符与表达式

两个整数相除结果为整数,两个浮点数相除结果为浮点数,如果两个操作数中有一个是浮点数,相除结果为浮点数

#include
int main(void)
{
	int i = 1;
	int j = 3;
	int a = i/j;
	printf("a = %d", a);
	getchar();
}
//a的输出结果为0
#include
int main(void)
{
	float x = 1;
	float y = 3;
	float z = x/y;
	printf("money is %f", z);
	getchar();
}
//a的输出结果为0.333333
#include
int main(void)
{
	float x = 1.0f/3;
	int y = 1/3;

	printf("x= %f", x);//0.333333
	printf("y= %d", y);//0
	getchar();
}

关系表达式

关系表达式的运算结果只有两种:0或者1。关系表达式的结果值是整数类型,c语言是没有boolean类型的值的

#include
int main(void)
{
	int x = 3;
	int y = 5;
	printf("%d\n", x>y);//输出0
	printf("%d", x!=y);//输出1
	getchar();
}

逻辑运算符

C语言提供的逻辑运算符有以下三种

&& 逻辑与

||逻辑或

!逻辑非(取反)

逻辑与和逻辑或都是双目运算符,需要两个操作数才能进行运算。逻辑非是单目运算符,只需要一个操作数就能运算

条件运算符

条件运算符一般的使用形式为:表达式1?表达式2:表达式3

如果表达式1为真,则选择表达式2,否则选择表达式3

sizeof运算符

sizeof,用于计算变量、字面量、类型所占字节数。该运算符是C语言中唯一一个使用单词作为运算符的

sizeof(类型/字面量/变量)

#include
int main(void)
{
	int x = 3;
	float f = 3.14f;
	double d = 3.14;
	printf("%d\n", sizeof(x));//4
	printf("%d\n", sizeof(f));//4
	printf("%d\n", sizeof(d));//8
    printf("%d\n", sizeof(int));//4
	printf("%d\n", sizeof(3));//4
	getchar();
}

几种基础的语句结构

1.赋值语句

2.函数调用语句

3.空语句

4.复合语句。使用{}将多行语句括起来就可以成为复合语句,复合语句中还可以嵌套复合语句

if语句

当if语句后面指定的语句只有一行时,可以不写{}。因为;才代表一行语句的结束

#include
int main(void)
{
	int x = 3;
	if(x > 1) printf("%d\n", sizeof(3));//输出4
	getchar();
}

if语句中的判断,把数值写在变量前面的好处是,可以通过编译来发现错误

//无论a的值为多少,总是会输出no ok,因为a=0是赋值语句,a始终为0
#include
int main(void)
{
	int a = 3;
	if(a=0){//实际想写a==0
		printf("ok");
	}else {
		printf("no ok");
	}
	getchar();
}
//此时0=a编译报错,能够发现错误。0==a则没有问题
#include
int main(void)
{
	int a = 3;
	if(0=a){//编译报错
		printf("ok");
	}else {
		printf("no ok");
	}
	getchar();
}

switch语句

switch后面跟一个语句块即可,语句块中包含多个以case开头,break结尾的语句

#include
int main(void)
{
	int a = 3;
	switch (a)//switch中的表达式的运算结果必须是整数类型,long、short、char、int等
	{
	case 1://case后面只能跟字面量表达式,运算结果也必须是整数类型
		{//大括号可有可无
		printf("test1");
		break;	
		}
	case 2:
		printf("test2");
		break;
	default:
		printf("test3");
		break;
	}
	getchar();
}

break非必需,但是如果没有beak,case不会退出,会继续向下执行,直到遇到break为止

#include
int main(void)
{
	int a = 1;
	switch (a)
	{
	case 1:
		printf("test1");
	case 2:
		printf("test2");
		break;
	default:
		printf("test3");
		break;
	}
	getchar();
}

输出

test1test2

函数

定义无参函数

类型名 函数名()
{
    语句;
}
//或者
类型名 函数名(void)
{
    语句;
}

定义有参函数

类型名 函数名(变量类型 变量值)
{
    语句;
}

自定义函数一般要放在调用它的函数之前,如果要放在调用它的函数之后,就需要添加函数声明,把函数的声明放到调用之前,函数的实现可以写到调用此函数的函数的后面

为什么会报错? 因为编译器发现一个不认识的函数调用,不知道该函数的返回类型,就假设为int类型,等后面编译的时候编译器看到实际的函数,它认为有两个同名的函数,一个是文件中的函数,一个是编译器假设返回int的函数

//这样写编译是会报错的
#include
int main(void)
{
	fun(1);

	getchar();
}

void fun(int i){
	printf("%d", i);
}
#include
//可以先声明函数,函数的实现可以不写
void fun(int i);

int main(void)
{
	fun(1);

	getchar();
}

//函数的实现可以写到调用此函数的函数的后面
void fun(int i){
	printf("%d", i);
}

疑问,为什么这样就可以,不会报错,可能和版本有关,最好是先声明函数,再写实现

并且int类型的函数,不需要返回值吗?没有返回值的时候,int类型的函数默认返回1

#include
//此时fun函数能够在main函数之后被定义和实现
int main(void)
{
	int i = fun(1);

	getchar();
}

int fun(int i){
	printf("%d", i);
}

数组

一维数组的定义方式为:数据类型 数组名[字面量表达式],比如int arr[10]。

数组长度可以是字面量或字面量表达式(比如int arr[5+5]也可以),但是不能是变量或变量表达式

一维数组的初始化方式可以为int arr[5]={1,2,3,4,5},这种全部初始化的方式

也可以使用部分初始化的方式

#include

void main()
{
    //初始化部分值,其余未被初始化的数组元素会被初始化为0
	int arr[4]={1,2};
	
	printf("%d\n", arr[0]);
	printf("%d\n", arr[1]);
	printf("%d\n", arr[2]);
	printf("%d\n", arr[3]);

 	getchar();
}
/*
输出
1
2
0
0
*/

由部分初始化的方式,有种取巧的方式,将一维数组全部初始化为0

int arr[5]={0};

定义数组时,可以不指定数组长度,,编译器会根据初始化列表计算出数组长度

比如:int a[5]={1,2,3,4,5};
可以写为:
int a[ ]={1,2,3,4,5};
[ ]中虽然没有指定数组长度,但系统会根据{ }中数据的个数确定数组 a 长度为 5

sizeof(数组名)就是数组的字节数,所以要获取数组长度,可以:sizeof(数组名)/sizeof(数组类型),或者sizeof(数组名)/sizeof(数组中任一元素)

sizeof(数组名)/sizeof(数组中任一元素)可以自动适应数组的类型,修改数组类型,计算结果也不会有问题

字符串

在C语言中,没有字符串类型的数据类型,用的是字符数组来存储字符串

为了区分普通字符数组和字符串,C语言规定以字符’\0’作为字符串结束标志。

char c[] ={'a','b','c'};//普通的字符数组,这个数组的长度为3
char c[] ={'a','b','c','\0'};//字符串,这个数组的长度为4,'\0'也占一个长度

没有’\0’的话,printf()函数输出的不会是字符串本来的样子。和数据在内存中的分布有关,会读到不应该读取到的内存

#include

void main()
{
	char c[] = {'c','d','\0'};
	//char c[] = "cd";
	printf("%s", c);
 	getchar();
}

简化写法,此时编译器会自动在字符串末尾添加’\0’

char c[] = "test";

如果把’\0’放在数组中间的位置,那printf()函数只会输出数组中’\0’前面的元素,数组本身的长度并没有变化

#include

void main()
{
	char c[] = {'c','d','\0','f','g'};//只输出cd
	char c1[] = "cd\0fg";//只输出cd
	printf("%s\n", c);
	printf("%s", c1);
 	getchar();
}

在C语言中,字符串的有效长度指的是字符串中’\0’之前的字符个数,不包括’\0’,比如

char c1[ ]={‘r’,‘u’,‘p’,‘e’,‘n’,‘g’,’\0’};
c1 字符串有效长度为 6,不包括最后的’\0’。
char c2[ ]=“rupeng”;
c2 字符串有效长度为 6,不包括系统自动添加的’\0’。
char c3[ ]={‘r’,‘u’,‘p’,‘e’,‘n’,‘g’};
c3 字符串有效长度就不一定是6,会读到不应该读取到的内存。

#include
#include

void main()
{
	char c[] = {'c','d','f','g'};
	char c1[] = "cdfg";
	printf("%s\n", strlen(c));//输出4
	printf("%s", strlen(c1));//输出4
 	getchar();
}

需要注意的是, strlen 函数内部只会计算字符串中’\0’之前的字符个数, ’\0’及之后的字符将被忽略。

#include
#include

void main
{
	char c[] = "ab\0cd";
	printf("%d\n", strlen(c));//输出2
	printf("%d\n", sizeof(c)/sizeof(c[0]));//输出6

 	getchar();
}

在程序的默认设置中, 1 个中文字符占 2 个字节。

#include
#include

void main()
{
	char c[] = "何宗玮";
	printf("%d\n", strlen(c));//输出6
	printf("%d\n", sizeof(c)/sizeof(c[0]));//输出7,包括最后的\0

 	getchar();
}

%c占位输出,会输出对应的字符;%d占位输出,会输出对应的ASCII码

#include
#include

void main()
{
	char c[] = "abcd";
	printf("%c\n", c[0]);//输出a
	printf("%d\n", c[0]);//输出97,ASCII码

 	getchar();
}
#include
#include

void main()
{
	
	printf("%d\n", 0);//输出0
	printf("%d\n", '\0');//输出0,猜想是\起到了转义的作用
	printf("%d\n", '0');//输出48

 	getchar();
}

字符串转为整型

头文件为include

#include
#include

void main()
{
	int i = 123;
	char c[] = {'1','2','3'};
	int i1 = atoi(c);
	printf("%d", i == i1);

 	getchar();
}

整型转字符串

函数原型char *itoa( int value, char* string,int radix);

value:要转换的整数。
string:要写入转换结果的目标字符数组。要确保目标字符串数组的长度要够用(只能多不能少),如果整数的位数是4位,那目标字符串数组的长度可以为5,因为要为最后的’\0’留地方。
radix:转换的进制,可以是 10 进制、 16 进制等。

#include
#include

void main()
{
	int i = 1234;
	char c[5] = {0};
	itoa(i, c, 10);
	printf("%s", c);//输出1234

 	getchar();
}

sprintf 字符串格式化函数

函数原型
int sprintf( char *buffer, const char *format, [ argument] … );

参数列表

buffer:保存格式化字符串的目标字符缓冲区(或者说目标数组)。 sprintf 会自动在最后加上’\0’
format:格式化后的字符串。 printf 里可以用的占位符, sprintf 里都能用
[argument]…:参数列表

#include

int main(void)
{
char buffer[24]={0};
sprintf(buffer,"name=%s,age=%d","sakura",20);
printf("%s",buffer);
getchar();
return 0;
}

你可能感兴趣的:(C语言,c语言,开发语言,后端)