c生万物之初识c语言

c生万物之初识c语言

前言:

1.初学习了c语言,感觉还是很不错的,哈哈~~。下面让我来分享下我目前对c的认识

题外:后面有关于c语言风格培养的《高质量的c-c++编程》PDF版链接,有需要自拿。哈哈~~。

一.初识c语言

1.1计算机语言的发展过程:由需求促进发展,由不成熟逐渐成为流行。

早期的科学家通过数字1和0的组合控制硬件计算机的运行。后来在需求下,人们创建了助记符(汇编语言).但还是不能满足需求,于是B语言出现,再后来高级语言C,c++,java等相继出现。但不同地方语言规范不同,为消除这种交流障碍,促进语言的融洽,1989年,ANSI(美国国家标准协会)制定了一套c语言规定(c89),1990年,国际标准化组织(IOS)也制定了一套规定(c90).1999年,ANSI/IOS(C9X委员会)联合委员会共同制定了c99;2011年,C9x发布了(C11)标准。至此C语言成为世界流行语言。目前使用较多的是c89/c90(2个几乎等同),

1.2什么是c语言?

c语言是一种面向过程的计算机编程语言,广泛用于底层C语言的设计目标 是提供一种 能简易编译,处理低级存储器,产生少量机器码以及不需要任何运行环境支持便能运行的编程语言。

选择C语言的理由:流行性,高效性,可移植性高,强大而灵活,面向程序员

1.流行性:c是一门流行语言。其融合了计算机科学理论和实践的控制特性。便于用户完成自顶向下的规划,结构化编程和模块化设计。使得c语言编写的程序更易懂,更可靠。
2.高效性:c是高效的语言。c语言具有通常汇编语言才有的微调控控能力,可以根据具体情况一获得最大运行速度,最有效的使用内存
3.可移植性高:c是可移植的语言。我们知道不同操作系统其运行方式不同。而我们想在不同系统运行c程序,需要我们在少量更改程序的条件下,仍能运行c程序。这必然要求我们的语言可移植性高。而在这些语言中,c语言崭露头角,其可移植性非常高
4.强大而灵活:许多操作系统,如UNIX系统大部分也是通过c语言编写的。另外很多程序编译器,解释器也是用c语言编写的。
5.面向程序员:c语言的强大,可以清晰的让程序员简洁的表达自己的想法与意图。

简单的c程序

#include<stdio.h>
int main()
{
    
    

printf("helloworld!");
return 0;
}

image-20210718085659275

据说在业界能这句话能给你的编程之旅带来好运!你好世界!

三.c语言的语法规则

3.1 c中的数据类型:整形,浮点型,字符型及其所占空间大小

整型 名字
int (普通整形),
short (int)可以省略(int) 短整形
long 长整形
long long 更长的整形
unsigned int 无符号(—)整形(只能为正)
signed int 有符号整型(一切整数)
浮点型: 名字
float 单精度浮点数型
double 双精度浮点型
char 字符型

3.1.2 每种数据类型的在内存中的大小

image-20210718095315310

补充:

1.sizeof(类型)
1.它是运算操作符,不是函数
2.它用于测定数据在内存中的字节(byte)大小,字符串结束标志‘\0’也要被计算内存。
2.strlen(字符数组名)
1.它是函数,不是操作符。
2.它用于测定字符数组长度。在测定长度时以’\0’为字符串结束标志。

3.字节(byte)

计算机的单位:

内存单位 名字 补充
bit 比特 计算机最小内存单元
byte 字节 1byte=8bit
kb 1kb=1024byte
mb 1kb=1024kb
gb 1kb=1024mb
tb 1kb=1024gb
pb 1kb=1024tb
我们知道计算机能识别的机器语言(二进制语言)(一定顺序的1/0),而对于每个二进制1/0在内存中都要占有一定的空间,我们规定每个这样的1/0所占的空间为1bit(计算机中的最小内存空间)。而计算机中的数据是按字节,分配空间的,即认为1byte为运行时的内存单元。
01000100 占用1个字节空间(8个bite位)

而对于数据类型我们规定:

类型 内存大小
整型(int) 4个字节(32bite位)
短整形(short) 2个字节(16个bite位)
long long型 8个字节。
类型 内存大小
字符型 一个字节(8个bite位)。
类型 内存大小
单精度型(float) 4个字节(32个bite位)
双精度型(double) 8个字节(64个bite位)。
==另外c语言规定:sizeof(long)>sizeof(int)=4;具体long型所占字节大小,依据不同编译器结果不同。

3.2变量,常量

3.2.1.变量:可以随时改变的量(数据).如:年龄,身高等;

3.2.2.常量:不能改变的量(数据)。如:圆周率,血型等。

3. 2.3定义变量的方式:

数据类型+自定义数据名称+初始化+语句结束标志“;”(分号)

初始化依据条件可以不进行初始化。

如 年龄是整形数据

身高是浮点型数据

字母是字符型数据

int age=19;
float length=170f;
char a='w';

3.2.4变量的使用:

#include<stdio.h>
int main()
{
    
    
int age=19;
float length=170f;//c默认浮点型数据为double型,如果非要float,只需要在后面加f;
char name[]="***";//名字是由多个字符组合成的,因此在c中我们定义字符数组来表示字符串;
printf("年龄=%d\n",age);
printf("长度=%f\n",length)printf("名字=%s",name);//以字符串的形式打印字符数组name中的每个元素;
return 0;
}

3.2.5变量的分类

局部变量:

定义在一对{}内的变量都是局部变量,无论是main函数还是普通函数。

全局变量:

不定义在main函数和其它函数内的都是全局变量。

注意

当全局变量与局部变量冲突时,遵从“局部变量优先原则

3.2.6变量的作用域与生命周期————有效使用变量

局部变量:

1.作用域:在所创建位置的一对{}内的任何地方都可以使用:
2.生命周期:
局部变量自创建的一对{}始,到出这对{}为止,这段时间为其生命周期;**

right:

image-20210718145758136

a创建于最外面的{},所以main函数内的任何地方都可以使用。

image-20210718150004939

a创建于里面的{},所以里面{}内的任何地方都可以使用。

error

image-20210718150314601

超出了a的作用域,printf无法调用a;

思考

#include<stdio.h>
int main()
{
    
    
    {
    
    
        int a=1;
        printf("%d\n", a);
    }
    printf("%d\n", a);
    return 0;
}
#include<stdio.h>
int main()
{
    int a = 1;
    {
        int a=1;
        printf("%d\n", a);
    }
    printf("%d\n", a);
    return 0;
}
全局变量:
1.作用域:自创建到程序结束的任何地方都可以使用。
2.生命周期:自创建到程序结束为其生命周期。

3.2.7常量:

1.字面常量:血型,名字等

2.const修饰常变量(一旦const就不可更改):

#include<stdio.h>
int main()
{
const int a=19;
a=22;//变量一旦const就不可更改,重新赋值。
printf("%d",a);
return 0;

}

3.#define定义的标识符常量

注意

1.define定义的宏常量不占用内存,它只会傻瓜式的语言替换。

image-20210718154601516

分析

结果并不是20,而是12的原因是:t=x+2*2;

4.枚举常量

当一个变量的所有可能可知的情况下,我们常定义枚举常量;如性别,数据类型等

image-20210718155806841

c语言规定:枚举常量中的第一个常量在数值上是0,其它依次加1。如果人为的初始化第一个常量,其它常量任然依次加1.**

image-20210718160620143

3.3字符与字符串+转义字符+注释;

3.3.1.字符与字符串:

字符:像‘w’这种由一对‘ ’所引用的字符。

字符串:”name“像这种用一对” “所引用的连续字符,称为字符串。

因为c语言中没有字符串型数据,因此我们用字符数组定义字符串;image-20210718161734039

3.3.2.转义字符:

补充:

1.在计算机中,为了方便字符型与实型数据间的运算,我们人为的规定每个字符对应的一个十进制数。为此我们制定了ASII表

注意

常用转义字符:‘\n’,’\t’,’\ddd’,’\xdd’;

image-20210718162612966

注意

c语言规定一个汉字是2个字节,算2个长度。**

image-20210718165013546

image-20210718164745807

3.3.3.注释

1.在c程序中我们想解释自己的程序时,我们常使用“//”;
2.在c程序中我们想保留部分程序,不让其起作用时,

注意

c的缺点:不能嵌套注释;

image-20210718172413204

3.4 c语言的3种结构:顺序,选择,循环。

3.4.1顺序:一步一步执行代码。

3.4.2选择结构(分支语句):

注意

c语言规定,表达式在逻辑上为0为假,非0为真。

3.4.2.1 if语句

1.if语句的2种形式
第一种
if(表达式){语句体}
else 语句体
第二种
if(表达式){语句体}
else if(表达式) {语句体}
else 语句体

注意

1.我们规定else最近的if匹配.
2.注意if语句体中的关键字break,continue;

看题

#include <stdio.h>
int main()
{
    
    
 int a = 0;
 int b = 2;
  if(a == 1)
        if(b == 2)
         printf("hehe\n");
    else
        printf("haha\n");
return 0;
}
思考这题的输出结果
答案:

什么都不输出思考注意中的第一点

2 .switch语句:

1.switch语句的形式

switch(整形表达式)

{

case 整形常量表达式:语句;

}

注意

1.switch中的整形表达式不可以浮点型数据,但可以为,枚举类型(可以当作是整形常量),字符型数据(计算机在碰到字符新数据时会将它自动转化为整形进行运算)(图一
2.case 中的必须为整形常量,或者是枚举类型(枚举也看以看作是一种特殊常量)
3.switch中的关键字break是用于分开语句块的。且不能使用关键字continue;(图二
4.当执行的case没有break作为跳出switch时,其会==,默认==继续执行下面的case,直到再次遇到break;(图三)
5.虽然switch中的default默认选项的意思,但使用时多留意其前面是否有break;再次体现第三点重要性(图四)
6.default 可以放在switch语句体内的任意位置

看图

图一

image-20210719232840650

图二

image-20210719233713420

图三

image-20210721091522206

图四

image-20210719234517389

问题

#include<stdio.h>
int main()
{
    
    
	int n = 1;
	int m = 2;
	switch (n)
	{
    
    
	case 1:
		m++;
	case 2:
		n++;
	case 3:
		switch (n)
		{
    
    //switch允许嵌套使用
		case 1:
			n++;
		case 2:
			m++;
			n++;
			break;
		}
	case 4:
		m++;
		break;
	default:
		break;
	}
				printf("m = %d, n = %d\n", m, n);
	return 0;
}

答案:

image-20210721092529211

分析:(1)-》(2)-》(3)-》(4)-》(5)

(1)先执行外面的swtich,n为1,执行case 1,后m=3.因为其后无break,进行执行case。
(2)执行case 2-》m=3,n=2.
(3)执行case 3->,执行内嵌的switch中的case 2-》m=4,n=3,遇到break,跳出内部switch
(4)执行case 4-》m=5.遇到break,跳出外部switch;
(5)m=5,n=3;

3.4.3循环结构:while,do while,for循环;

1.while语句形式

while(表达式){语句体}
表达式为真是,执行语句体.

2.do …while语句形式

do{语句体}while(表达式);
执行语句体,后判断表达式

3.for语句形式

for(表达式1,表达式2,表达式3)
表达式1:
表达式1为初始化部分,用于初始化循环变量的。
表达式2:
表达式2为条件判断部分,用于判断循环时候终止
表达式3:
表达式3为调整部分,用于循环条件的调整

注意

1.while的执行条件始终比循环体多一次
2.do while语句注意语句结束要有分号"";“,且其循环体始终与表达式执行次数一致。
3.brake只能跳出一层循环(当内循环结构时,只能跳出内部一层循环结构)
4.continue只能跳出本次循环。

练一练

打印9*9乘法表

for()形式

int main()
{
    
    
	int i = 0;
	int j = 0;
	for (i = 0; i < 10; i++)
        for (j = 1; j <= i; j++)
		{
    
    
			printf("%d*%d=%-2d", i, j, i * j);
            if (j == i)printf("\n");
		}
	return 0;

}

分析:通过i控制行,j控制列.

while形式

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int main()
{
    
    

	int i = 1;
	int j = 0;
	while (i < 10)
	{
    
    
		j = 1;
		while (j <= i) 
		{
    
    
			printf("%d*%d=%-3d", i, j, i * j);
			j++;
		}
		printf("\n");
		i++;
	}
	
	
	
	return 0;
}

分析:外层循环控制行,层控制列

do while形式

int main()
{
    
    

	int i = 1;
	int j = 0;
	do
	{
    
    
		j = 1;
		do
		{
    
    
			printf("%d*%d=%-3d", i, j, i * j);
			j++;
		} while (j <= i);	
		printf("\n");
		i++;
	} while (i<10);
	
	
	return 0;
}

分析:外层循环控制行,层控制列

3.5函数

背景:在一个main函数中,我们可以通过代码的形式完成某些目的,但是这样,main函数就会变得很长。为了尽可能的减少main函数的代码长度,我们创建函数来完成这部分工作。

函数形式:

返回值类型+函数名+(形参1,形参2,…)

#include<stdio.h>
int add(int x,int y)
{
    
    

return x+y;
}
int main()
{
    
    

  int a = 0;
  int b = 0;
  int c = 0;
  scanf("%d%d",&a,&b);
  c=add(a,b);
  printf("%d\n",c);
    
  return 0;
}

函数声明形式:

返回值类型+函数名+形式类型+”;“

#include<stdio.h>

int main()
{
    
    
int add(int x,int y);//函数声明

  int a = 0;
  int b = 0;
  int c = 0;
  scanf("%d%d",&a,&b);
  c=add(a,b);
  printf("%d\n",c);
  
  return 0;
}
int add(int x,int y)
{
    
    

return x+y;

}

注意

1.自定义的函数要有返回值.
2.自定义的函数可以放在main函数的前面,或者后面(在后面的时候,要在main函数中提前声明)。
3.实参传递数据到形参时,参数类型要相同,不然会丢失部分数据

3.7数组

背景:如果我们想存储一组数,我们一个怎么办呢?这时候即需要c中的数组;

3.7.1数组的定义:

数组元素类型+数组名+【数据数量】;

int arr[10]={
    
    1,2,3,4,5,6,7,8,9,10};

3.7.2数组下标:

int arr[10]={
    
    1,2,3,4,5,6,7,8,9,10};

数组长度是10,下标从0~9

3.7.3数组的使用

#include <stdio.h>
int main()
{
    
    
int i = 0;
int arr[10] = {
    
    1,2,3,4,5,6,7,8,9,10};
for(i=0; i<10; i++)
{
    
    
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}

注意

1.数组下标小于数组长度,且其最大值为数组长度-1;
2.数组名是数组的首地址;

看题

下面程序有问题吗?

#include<stdio.h>
int main()
{
    
     
    int i = 0;
    int arr1[10]={
    
    0};
    char arr2{
    
    10}={
    
    0};
    char arr3[10]={
    
    '0'};
    printf("%d\n",arr1[0]);
    printf("%c\n",arr2[0]);
    printf("%c\n",arr3[0]);
    
  return 0}

image-20210721172234931

分析:

arr1[0]被初始化为0;arr2[0]被初始化为0;arr3[0]被初始化为字符’0’;
0 对于int 型 就是数字0,但对char ,在ASII表中是 空 的意思,即没有任何意义(NULL)。
字符’0’对于char 型是字符串结束标志。

3.8操作符

3.8.1算术操作符:

+,-,*, /,%

注意

除法的2种情况:
/的前后都是整形数据时,对结果取整
/的前后存在浮点数时,结果就是浮点数。(图一)
% 取余
%的前后必须是整形数据
#include<stdio.h>
int main()
{
    
    
int a =0;
int b =0;
int c2 =0;
float c2 =0;
scanf("%d%d",&a,&b);
c1=a/b;
c2=a/b;
printf("%d\n",c1);
printf("%f\n",c2);

return 0;
}

image-20210721181102475

3.8.2位移操作符:

<<,左位移操作符

>>右位移操作符

它们移动的是补码

补码补充

1.计算机在内存中处理数据,都是按数据的补码形式进行运算的,最后以原码的形式表现数据。
2.正数与0的,原码,反码,补码是一样的。
3.负数的原码按正数编时的二进制原码反码是原码除符号位,其它位取反补码反码+1

题目

#include<stdio.h>
int main()
{
  int a=-1;
  int b=-1;
  printf("%d\n",a<<2);
  printf("%d\n",b>>2);

  return 0;
}

image-20210721184143358

image-20210721191836386

3.8.3位操作符:&,|,^

注意

运算符 功能 运算规则
& 按位与 对应位均为1时,才位1,否则为0
| 按位或 对应位存在1时就为1
^ 按位与或 对应位相同为0,相异为1
<< 左移 补码左移若干位,超出丢弃(不包括1),剩下补0,每左移一位,相当于多乘2;
>> 右移 补码右移若干位,正数左补0,负数左补1,右边溢出丢。

3.8.4赋值操作符:=,+=,-=,*=,/=,&=,|=,<<=,>>=

3.8.5单目操作符:

单目操作符表

单目操作福 功能
逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 就类型长度(以字节为单位)
~ 对一个数的补码按位取反
前置:先自减,后应用;后置:先应用,后自键
++ 前置:先自增,后应用;后置:先应用,后自增
* 间接访问操作符(解应用操作符)
(类型) 强制类型转换

3.8.6关系操作符:

>,>=,<,<=,==,!=;

3.8.7逻辑操作符(双目运算符):

逻辑操作符 功能
&& 且,只有当2边逻辑都为真是才为真
|| 或,一边为真即为真

3.8.8条件操作符

exp1?exp1:exp2

3.8.9逗号表达式:

exp1,exp2,exp3…

注意

逗号表达式的运算结果以最后一项为准。

看图

image-20210721195412928

3.8.10下标引用[],函数调用(),结构体成员->.

3.9关键字

关键字 功能
auto 存储类别说明关键字(局部变量)
break 终止一层循环
case swtich语句中的case
char 字符数据类型说明关键字
const 将变量定义为长量
continue 结束本次循环,直接执行下次循环
default switch语句中,当没有满足case的情况,默认执行default语句
do do {}while();语句中的关键字
double 双精度数据类型说明关键字
else 与最近if匹配的else分支语句
enum 枚举变量的说明关键字
extern 提前告知变量,函数等出现在别的文件中
float 单精度数据类型说明关键字
for for的说明关键字
goto C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。
if 分支语句说明关键字
int 整形数据说明关键字
long 更大整形说明关键字
return 返回某种类型的值,结束函数
short 短整形说明关键字
signed 有符号型说明关键字
sizeof 测定数据占内存空间的大小,单位字节
static 静态成员说明关键字(具体说明看下面)
struct 结构体说明关键字
switch swtich分支语句关键字
typedef 重新定义数据类型别名:typedef unint unsigned int
union 联合说明关键字
unsigned 无符号整形说明关键字
void 空类型说明关键字
while while语句说明关键字
register
volatile

注意

在定义变量,函数名时不能使用关键字

3.9.1static:

1.修饰局部变量:延长局部变量生命周期不改变作用域(图一)
2.修饰全局变量:改变全局变量的外联性(可被其它文件使用。extern),使全局变量只能被本模块使用。
3.修饰函数:改变函数的外联性(可被其它文件使用。extern),使函数只能被本模块使用。

图一

image-20210721202905771

图二

image-20210721210951825

图三

image-20210721211544673

3.10#define定义宏常量和宏

#define+“空格”+宏常量名+常量
#define+“空格”+宏名+表达式
image-20210721212115049

3.11指针

3.11.1内存:

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。

3.11.2内存是怎么被编号的?

我们知道32位计算机有32根物理地址线(通过地址线,寻找相应地址的数据),在通电时,每根电信号被转化为1/0。而这样的32跟地址线,可形参232种不同的32为位二进制编码。二232字节换算成G时为4G,在32为系统4G内存足够了。因此以这 232种二进制(其实是将二进制转化为16进制,编号内存的)为编号刚好,(另外通过增加地址线的方法,可以增加内存)

3.11.3地址的存储

通过指针变量,我们能存放地址。

3.11.4指针变量:

定义:要存地址的类型+指针变量名+=地址;
指针的作用:通过所存储的地址,寻找其数据
image-20210721215527444

3.11.5指针的大小:

前面我们知道,32系统下的32为地址线,通过32位二进制编号内存,所以在内存中我们存储一个地址时需要4个字节的内存单元,即32位下指针大小为4字节。同理64位系统下,指针大小为8字节
image-20210721220123770

3.11.6补充

我们在定义变量时,随机存储在内存中。当程序结束时,变量内存释放。每次运行,变量都随机存储于内存中。

3.12结构体

前言

生活中我们经常遇到具有共同属性的一类事物,如:人
对于人这个抽象概念,我们很模糊,但我们具体到某个人时,他的名字,性别等,做为他的具体属性被我们知道。
因此我们定义结构体,用于对具有共同属性的一类事物的抽象

3.12.1结构体定义:

struct+结构体名

{

属性1;

属性2;

};

注意

1.定义结构体不可丢关键字struct
2.结构结尾的分号不能丢

3.12.2结构体数组:

在这里插入图片描述

| ------------------------------------------------------------ |

感言:

1.对目前c语言的有些地方学的不深,不敢过多描述。哈哈。

2.在这段学习中,我会了一些小游戏,由其是关机程序,贼有意思!哈哈。后面会补上的。

3.《高质量的c-c++编程》PDF版链接:链接:https://pan.baidu.com/s/1yW6FgsZDqeOtVzePrdZk_Q

提取码:2021

猜你喜欢

转载自blog.csdn.net/qq_55439426/article/details/119003621