天天看点

偷学C语言第一天

目录

从“Hello world!”开始

代码解释

#include

stdio

.h

<>

main()函数

/**/

printf()

return

C程序结构

写的第一个C语言Bug

数据类型

标识符 

变量和常量

变量

常量

多学一点

比特位和字节

符号位(signed&unsigned)

从“Hello world!”开始

#include <stdio.h>
int main(){
	/*第一个C程序*/
	printf("Hello world!\n");
	return 0;
}           

代码解释

#include

是在程序编译之前要处理的内容,称为编译预处理命令。编译预处理命令还有很多,它们都以“#”开头,并且不用分号结尾,是c语言的程序语句。我猜测“include”这个东东就类似于Java中的导包,举个通俗的例子,我们要做某件事情,别人是做这件事情的专家,那么专业的事情就交给专业的人去做,所以我们得先把专家请过来,#include<stdio.h>就相当于你先把“stdio.h”这个可以完成标准输入输出的专家请过来,在需要输入输出时直接调用它里面的函数即可。

stdio

stdio是C编译系统提供的一个文件名,stdio是“standard input & output”的缩写,即有关标准输入输出的信息。

.h

h即head,表示头文件,因为这些文件都是放在程序各文件的开头。

<>

表示系统自带的库,也可以写成" " 表示用户自定义的库,如果写成" "并且自定义的库里面没有这个文件系统会自动查找自带的库,如果还是没有就会报错。

main()函数

与Java相同,mian()函数是C语言程序入口,既然是入口,那在一个C程序中就只能有一个main()函数,可没有后门噢(~_~)。int是函数的返回值类型,也就说你这个函数在执行完成之后,要返回给调用者什么玩意,当然也可以不返回,此时可以指定返回值类型为void或者直接省掉。

#include <stdio.h>
void main(){
	printf("Hello world!\n");
}           

在撸码时我发现以下写法都不会报错,原来C并不是那么严谨,可能我刚开始学C,理解的还不够,这个问题先记在小本本上,高手也可以在评论区留言帮我解惑,不胜感激{>_<}~

#include <stdio.h>
main()
{
 double d = 3.1415926;
 printf("Hello world!\n");
 return d;
}

#include <stdio.h>
int main()
{
	printf("Hello world!\n");
}


#include <stdio.h>
void main()
{
 printf("Hello world!\n");
}

#include <stdio.h>
main()
{
 printf("Hello world!\n");
}           

/**/

C语言的注释,是给开发人员看的,计算机不会理会注释。

printf()

print是打印的意思,f即format,所以printf是格式化打印,也叫格式化输出。详情请看:printf函数文档

return

使用return关键字结束程序,并返回我们指定的数据。

C程序结构

从上述案例中我们可以总结出,一个C语言程序包含:预处理器命令、函数、变量、语句、注释,除此之外,后面我们还会学到表达式。

写的第一个C语言Bug

#include<stdio.h>
int main()
{
	printf("
     *********
   |:H:a:p:p:y:|
 __|___________|__
|^^^^^^^^^^^^^^^^^|
|:B:i:r:t:h:d:a:y:|
|                 |
*******************
                  ,;,,;
                 ,;;'(    生
       __      ,;;' ' \   ┇
    /'  '\'~~'~' \ /'\.)  日
 ,;(      )    /  |.      ┇
,;' \    /-.,,(   ) \     快
     ) /       ) / )|     ┇ 
     ||        ||  \)     乐
     (_\       (_\n");
return 0;
}           

缘起:铁哥们今天过生日,作为程序员的我想搞个特别的生日祝福,于是就有了上面的程序,printf既然可以输出“Hello world”,那我让它多输出点东西应该没问题吧,结果:

偷学C语言第一天

小朋友,你是不是有很多问号?哈哈哈~ 经过一番百度,原来需要用“\n”来换行,用“\”作为上一行和下一行的“连接符”(我们暂且叫它连接符),"\n"是C语言的转义字符,在字符串中反斜杠 + 字符是转义字符,表示特殊含义。但反斜杠如果后边不带任何字符(直接换行),表示我们希望 C 语言将该行以及下一行看做是一个整体。来看看修改后的代码:

#include<stdio.h>
int main()
{
	printf("\n\
     *********\n\
   |:H:a:p:p:y:|\n\
 __|___________|__\n\
|^^^^^^^^^^^^^^^^^|\n\
|:B:i:r:t:h:d:a:y:|\n\
|      小马       |\n\
*******************\n\
                  ,;,,;\n\
                 ,;;'(    生\n\
       __      ,;;' ' \   ┇\n\
    /'  '\'~~'~' \ /'\.)  日\n\
 ,;(      )    /  |.      ┇\n\
,;' \    /-.,,(   ) \     快\n\
     ) /       ) / )|     ┇ \n\
     ||        ||  \)     乐\n\
     (_\       (_\n");
return 0;
}           
偷学C语言第一天

虽然有警告,但是没有报错了,而且也能正常打印出颜文字了。

PS:下面的转义字符表不用刻意去记,常用自然会用。

转义字符 意义 ASCII码值(十进制)
\a 响铃(BEL) 007
\b 退格(BS) ,将当前位置移到前一列 008
\f 换页(FF),将当前位置移到下页开头 012
\n 换行(LF) ,将当前位置移到下一行开头 010
\r 回车(CR) ,将当前位置移到本行开头 013
\t 水平制表(HT)  009
\v 垂直制表(VT) 011
\' 单引号 039
\" 双引号 034
\\ 反斜杠 092

常用ASCII码对照表

数据类型

在C语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式。通俗地讲,我们的数据是存储在内存中的,内存就好像是一幢摩天大楼,里面被分成了大大小小的房间,我们的数据就被存储在这些房间里,房间的编号就是内存地址,房间的大小及内部布局就是由数据类型决定的。

常用的数据类型包括基本类型、指针类型、数组类型、结构类型等。(数组类型和结构类型统称为构造类型或聚合类型,函数的类型指的是函数返回值的类型。) 

偷学C语言第一天

关于标准整数类型的存储大小和值范围的细节

类型 存储大小 值范围
char 1 字节 -128 到 127 或 0 到 255
unsigned char 1 字节 0 到 255
signed char 1 字节 -128 到 127
int 2 或 4 字节 -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
unsigned int 2 或 4 字节 0 到 65,535 或 0 到 4,294,967,295
short 2 字节 -32,768 到 32,767
unsigned short 2 字节 0 到 65,535
long 4 字节 -2,147,483,648 到 2,147,483,647
unsigned long 4 字节 0 到 4,294,967,295

关于标准浮点类型的存储大小、值范围和精度的细节

类型 存储大小 值范围 精度
float 4 字节 1.2E-38 到 3.4E+38 6 位小数
double 8 字节 2.3E-308 到 1.7E+308 15 位小数
long double 16 字节 3.4E-4932 到 1.1E+4932 19 位小数

各种类型的存储大小与系统位数有关,但目前通用的以64位系统为主。 为了得到某个类型或某个变量在特定平台上的准确大小,C为我们提供了sizeof运算符,代码示例:

#include<stdio.h>
void main()
{
	int i = 666;//i是变量
	/*sizeof的三种使用方式:
	  sizeof(对象)
	  sizeof 对象
	  sizeof(类型)
	*/
	printf("整型的存储大小是:%d\n",sizeof(i));
    printf("整型的存储大小是:%d\n",sizeof i);
    printf("整型的存储大小是:%d\n",sizeof(int));
}           

PS:我们可以为基本数据类型加上一些限定符,比如表示长度的 short 和 long。比如 int 经过限定符修饰之后,可以是 short int,long int,还可以是 long long int(这个是 C99 新增加的)。 

标识符 

 标识符是用来标识变量、函数,或任何其他用户自定义项目的名称。标识符的命名规范如下:

  • 只能是英文字母(A~Z、a~z)、数字(0~9)、下划线(_)组成。
  • 第一个字母必须是字母或下划线开头。
  • 标识符区分大小写。
  • 不能使用关键字命名。

变量和常量

变量

变量就是可以改变的数据。我们让CPU帮我们处理的数据都被它放在了内存里(可以理解为一个个坑位,一个萝卜一个坑),每个内存都有内存地址(坑位编号),而我们需要给变量取名再把它放进内存里,这样做的好处就是我们可以通过直呼其名的方式获取变量在内存中保存的数据。

声明变量的语法:数据类型 变量名;

/*演示变量*/
#include<stdio.h>
void main()
{
	/*先声明变量*/
	int i ;
    /*再给变量赋值,业内称该操作为给变量初始化*/
    i = 666;
	float f = 3.14F;
	double d = 31415926E-7;
	
	printf("i = %d\n",i);
	printf("f = %3.3f\n",f);
	printf("d = %.7f\n",d);
}           

PS:C语言关键字就是C语言自己内部使用的名字,这些名字都具有特殊意义,不允许外部使用。传统的 C 语言(ANSI C)有 32 个关键字:auto、break、case、char、const、continue、default、do、double、else、enum、extern、float、for、goto、if、int、long、register、return、short、signed、sizeof、static、struct、switch、typedef、union、unsigned、void、volatile、while;1999年,ISO 发布 C99,添加了 5 个关键字:inline、restrict、_Bool、_Complex、_Imaginary;2011年,ISO 发布 C11,添加了 7 个关键字:_Alignas、_Alignof、_Atomic、_Static_assert、_Noreturn、_Thread_local、_Generic。

常量

就是恒量,不变的量,正所谓“强者恒强”~

常量的分类

  • 整型常量

    整型常量可以是八进制、十进制、十六进制,前缀指定基数,后缀指定类型,比如:30UL表示无符号长整型30,0x4b表示十六进制的4b。

    注:前缀“0x”/"0X"表示十六进制、"0"表示八进制,不带前缀默认十进制;后缀u/U表示无符号(unsigned),l/L表示长整型(long)。

  • 浮点常量(实型常量)

    浮点常量有两种表示形式,即小数形式和指数形式。当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时,必须包含小数点、指数,或同时包含两者。带符号的指数是用e或E引入的。

  • 字符常量

    字符常量被括在单引号中,像这样的'a',字符常量可以是一个普通的字符(例如 'a')、一个转义序列(例如 '\t'),或一个通用的字符(例如 '\u02C0')。

  • 字符串常量

    字符串字面值或常量是被括在双引号 "" 中的,字符串你可以理解为文本,例如“Hello world!”。

  • 定义常量(宏定义)

    在C中我们可以通过 #define 预处理器和const关键字定义常量。关于两者的区别,可以看看这篇:const和#define的区别,详细!

#include<stdio.h>

/*定义常量方式一:
格式:#define 标识符 常量值

它的功能就是把程序中所有出现的该定义的标识符都替换为随后的常量。
*/
#define MAX 800
int main()
{
	/*整型常量*/
	int i = 888;
	/*单浮点型常量,浮点型默认是double,使用f/F后缀可以指定为float类型*/
	float f = .5F;
	/*双浮点型常量*/
	double d = 314.15926E-2;
	/*字符常量*/
	char c = 'a';
	/*字符串常量:C语言中用'\0'这个特殊的转义字符标记字符串的结束位置,
	这样以来,当操作系统读取到这个转义字符时,就能知道字符串到此为止了。
	*/
	char chs[] = "学习使我快乐{>_<}";
	/*定义常量方式二:
	  格式:const 类型 标识符 = 常量值;
	*/
	const int CAPACITY = 16;
	
	
	/*printf 函数文档:https://fishc.com.cn/thread-66471-1-1.html*/
	printf("i = %d\n",i);
	printf("f = %.1f\n",f);
	printf("d = %8.7f\n",d);
	printf("c = %c\n",c);
	printf("chs = %s\n",chs);
	printf("MAX = %d\n",MAX);
	printf("CAPACITY = %d\n",CAPACITY);
}           

多学一点

比特位和字节

  • 比特位(bit)是CPU能读懂的最小单位,用"b"表示,只能存放二进制的0和1。
  • 字节(Byte)是内存结构的最小寻址单位,用"B"表示。
  • 一字节等于八位:1Byte==8bit。所以一字节可以存储最大的数是:11111111。

符号位(signed&unsigned)

signed(带符号位)和unsigned(不带符号位)叫做类型限定符,用于限定char和任何整型变量的取值范围。带符号位的变量可以表示负数,最高位用1表示负数,0表示正数;而不带符号位的变量只能表示正数,它的存储空间也就相应扩大一倍。默认所有的整型变量都是 signed的,也就是带符号位的。

我们看个例子:

#include<stdio.h>
#include<math.h>
int main()
{
	/*默认是有符号的,即signed*/
	short i = -1;
    /*无符号的变量只能接受整数,如果硬要把负数赋值给它,编译器
	会提示你“[-Woverflow]”,运行代码将会出现奇葩的结果
	*/
	unsigned short j = -1;
	/*计算int类型可以存储的最大值 ------ 这行代码是有问题的*/
	int maxIntError = pow(2,32)-1;
	/*计算int类型可以存储的最大值 ------ 这行代码才是正确的*/
	unsigned int maxInt = pow(2,32)-1;
	
	printf("i = %d\n",i);
	printf("j = %d\n",j);
	printf("maxIntError = %d\n",maxIntError);
	printf("maxInt = %u\n",maxInt);
}           

继续阅读