探索C语言的奥秘:从初识开始

        学习一门编程语言是一条艰辛与快乐共存的一条路,如今选择了这条路,就应该一直走下去,了解C语言的基础知识,要先对C语言有一个大概的认识,下面我介绍一下C语言的基础。

一、什么是C语言。

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

        尽管C
语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的 C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式
处理器
(单片机或称
MCU
)以及超级电脑等作业平台。

        二十世纪八十年代,为了避免各开发厂商用的C
语言语法产生差异,由
美国国家标准局

C
语言制 定了一套完整的美国国家标准语法,称为
ANSI C
,作为
C
语言最初的标准。
[1]
目前
2011

12

8 日,国际标准化组织(ISO
)和国际电工委员会(
IEC
)发布的
C11
标准

C
语言的第三个官方标准,也是C
语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。

        C语言是一门面向过程的计算机编程语言,与
C++

Java
等面向对象的编程语言有所不同。

其编译器主要有
Clang

GCC

WIN-TC

SUBLIME

MSVC

Turbo C
等。

二、C语言编程代码的基本格式。

        

#include <stdio.h>
int main()
{
    printf("Hello\n");
    printf("Just do it!\n");
    return 0; 
}

       打印结果:

有\n(这是换行操作符,下面会介绍)

无\n

        2.1 #include <stdio.h> :每一个C语言程序代码都含有的一个头文件,其中include 称为文件包含命令,其意义是把尖括号<>或引号""内指定的文件包含到本程序中,成为本程序的一部分。被包含的文件通常是由系统提供的,其扩展名为.h,而stdio为standard input output的缩写,意为“标准输入输出” ,在程序中为固定格式,输入上去就行。

       2.2 int main()main函数是程序的入口 ,一个工程中main函数有且仅有一个,是C语言main函数的一种声明方式,在int main()下有一对{},在其中输入代码。

       2.3 printf:表示要输出的结果,其结果放入("  ")中的双引号内,如果需要特别打印某一种字符类型,一般格式为(“需要打印的数据类型\n”,需要输出的变量)蓝色部分表示固定的格式。绿色部分表示需要打印相应内容时输入的不同的东西,\n表示换行,可有可无,只是打印出的结果格式不同不影响打印内容,具体需要打印的类型见后边。

       2.4 return 0返回值为0,先不做深入了解,记作固定的格式,打上去就行。

注:每一个语句后面需要打上一个英文输入下的分号  ;

三、数据类型

char             
字符数据类型

short           
短整型

int               
整形

long             
长整型

long long     
更长的整形

float             
单精度浮点数(
有效数字8位,表示范围:-3.40E+38~3.40E+38

double         
双精度浮点数(
有效数字16位,表示范围:-1.79E+308~-1.79E+308

注:每一种类型的空间大小不同

各种数据类型的空间大小:

#include <stdio.h>
int main()
{
    printf("%d\n", sizeof(char));
    printf("%d\n", sizeof(short));
    printf("%d\n", sizeof(int));
    printf("%d\n", sizeof(long));
    printf("%d\n", sizeof(long long));
    printf("%d\n", sizeof(float));
    printf("%d\n", sizeof(double));
    printf("%d\n", sizeof(long double));
    return 0; 
}

        代码中%d打印的是整型,sizeof()用于打印数据类型的大小。

打印结果:

         其中数字大小表示各种数据类型的空间大小,单位为字节(byte)1GB=1024MB 1MB=1024KB 1KB=1024byte     1字节=8位       其中位:是二进制数据中的一个位(bit)简写为b,音译为比特,是计算机存储数据的最小单位。

四、常量与变量

常量:
不变的值,
C
语言中用
常量
的概念来表示,在生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)。

变量:
变的值,
C
语言中用
变量
来表示(比如:年龄,体重,薪资)。

        
4.1 定义变量的方法

int age = 150;
float weight = 45.5f;
char ch = 'w';

        选择需要定义变量的类型(int、char、float等),给变量相应的变量名字(自己灵活定义即可,最好方便自己记忆,比如需要对年龄赋值时,变量名用age),用 = 进行赋值,将值放在等号后面,并习惯性的打上分号。

        4.2 变量的分类

全局变量:定义在int main()以外,对整个代码有效

局部变量:定义在某一个范围内用{ }括起来的区域,当出了该范围则无效,如果全局变量和局部变量一起存在,则局部变量优先。

#include <stdio.h>
int b = 2020;            //全局变量
int main()
{
    int b = 2021;        //局部变量
    
    int c = 2022;        //局部变量
    printf("b = %d\n", b);
    return 0;
 }

打印结果:

4.3 变量的使用

        我们以计算两个数字的和为例

#include <stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = num1 + num2;
    printf("sum = %d\n", sum);
    return 0; 
}

      随机输入两个数字  

 

        代码中先定义需要输入的两个数字整型int num1=0;int num 2=0;其中赋一个初始值0,在定义一个变量来存放需要输出的值int sum=0;均放上初始值0;先输出一个提示语输入两个操作数:>用scanf(“%d %d”,&num1,&num2)来寻找变量num1和num2的地址,达到对变量随时赋值的目的,sum=num1+num2定义算法,即求两个数的和,并将结果用变量sum来承接,最后用printf来输出sum的值。

4.4 变量的作用域和生命周期

        1.作用域:
是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效,可用

的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

                1. 局部变量的作用域是变量所在的局部范围。

                2. 全局变量的作用域是整个工程。

        2.生命周期:
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段

                1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。

                2. 全局变量的生命周期是:整个程序的生命周期。

4.5 常量

C语言中的常量和变量的定义的形式有所差异

        1.字面常量:即已知的值

        2.const 修饰的常变量:对所赋值的变量有固定作用,后续不能改变

#include <stdio.h>
int main()
{
	const int num = 4;
	printf("%d\n", num);
	int num = 8;//此处对num再赋值已经无效了
	printf("%d\n", num);
	return 0;
}

         其中const修饰的常变量,对赋值的sum有固定作用,后面再对num赋值则无效,虽然对num固定赋值了,但num的本质任然是变量,只是具有了常量的性质,验证如下:

#include <stdio.h>
int main()
{
	const int n = 10;
	int arr[n] = { 0 };//数组[]中需要的是一个常量,虽然const修饰的n有常属性,但是他的本质是一个变量所以有错误
	return 0;
}

所以没有输出结果:

        

        3.#define 定义的标识符常量 :定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了。例如:对MAX的赋值,在main函数外定义。

#include <stdio.h>

#define MAX 10
int main()
{
	int arr[MAX]={0};
	printf(" %d\n", MAX);
	return 0;
}

 

        4.枚举常量:需要一一列举出来,需要用到枚举关键字enum,放在枚举里边的叫枚举常量    

#include<stdio.h>
enum people
{
	KID,
	MAN,
	WOMAN,
};                //其中KID,MAN,WOMAN,叫做枚举常量
int main()
{
	printf("%d\n", KID);
	printf("%d\n", MAN);
	printf("%d\n", WOMAN);
	return 0;
}

五、字符串+转义字符+注释

       
5.1 字符串:
这种由双引号(Double Quote
)引起来的一串字符称为字符串字面值(
String Literal),或者简称字符串。比如第一个代码中的 "Just do it!\n"

#include <stdio.h>
int main()
{
    printf("Hello\n");
    printf("Just do it!\n");
    return 0; 
}

       
5.2 转义字符:转义字符是以“\”为开头的字符,后面跟一个或几个字符,其意思是将反斜杠“\”后面的字符转变成为另外的意思。

转义字符 释义
\0 结束标志
\?

在书写连续多个问号时使用,防止他们被解析成三字母词

\'

用于表示字符常量
'

\"

用于表示一个字符串内部的双引号

\\

用于表示一个反斜杠,防止它被解释为一个转义序列符。

\a

警告字符,蜂鸣

\b

退格符

\f

进纸符

\n

换行

\r

回车

\t

水平制表符

\v

垂直制表符

\ddd

ddd
表示
1~3
个八进制的数字。 如:
\130 

\xdd

dd
表示
2
个十六进制数字。 如: \x30         

        1.先给大家介绍一下结束标志\0

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

打印结果:

         字符串放在数组里面时,末尾会默认输入一个 \0,也就是说在数组char arr1 [ ]={"bit"}中,其实放入的内容有‘b’,‘i’,‘t’,‘\0’,所以打印完bit后就结束了,然而在数组char arr2 [ ]={‘b’,‘i’,‘t’}这种单独的字符时,末尾是不会默认输入\0 的,所以在打印完bit以后并没有结束打印,而是打印了一些随机值。故出现一些“烫烫烫烫烫烫烫烫烫烫烫烫烫烫蘠it”,如果手动在末尾输入 \0 时,就手动给了一个结束标志,如数组char arr3 [ ]={‘b’,‘i’,‘t’,‘\0’},打印完bit遇到了\0,那么就结束打印。

       

        2.转义字符 \? :在书写连续多个问号时使用,防止他们被解析成三字母词,三字母词存在于老一版的编译器中。

#include<stdio.h>
int main()
{
	printf("(are you ok\?\?)\n");//   \?在书写连续多个问号时使用,防止他们被解析成三字母词
	return 0;
}

打印结果:

  

        3.转义字符 \' 与 \" :只是单纯的为了输出单引号和双引号

#include<stdio.h>
int main()
{
	printf("\'");
	printf("\"");
	return 0;
}

打印结果:

       
4.转义字符 \t :水平制表符,输出结果相当于一个按一次Tab健所拉开的距离

#include<stdio.h>
int main()
{
	printf("a\ta");
	return 0;
}

输出结果:

              其中两个字母a之间的间隔就是 \t 所拉开的一个Tab的距离

        5.转义字符\ddd和\xdd:
ddd
表示
1~3个八进制的数字。 如: \130 ,

                                        

                                               
dd
表示
2
个十六进制数字。 如:
\x30

                                               打印时输出的是对应表示的进制转化为十进制后,十进制对应ASCII码表对应的字符。

#include<stdio.h>
int main()
{
	printf("\101\n");
	printf("\x42");
	return 0;
}

输出结果:

        其中八进制\101转化为十进制表示的数是65,十六进制\x42转化为十进制表示的数是66

 
        6.转义字符 \\:
用于表示一个反斜杠,防止它被解释为一个转义序列符,相当于将已经用 \ 转义的字符取消,如同双重否定是肯定的效果。而 \\ 在代码中还有一个最常用的用法,用来解释代码意思,方便理解相应代码的功能,也方便他人阅读。

#include<stdio.h>
int main()
{
	printf("c:\\test\41\test.c");       
	return 0;
}

输出结果:

          其中\t叫作水平制表符相当于以一个tab健的一个空格位置,为防止\t被识别成转义字符,规定\\为反斜杠,防止他被解释为一个转义字符,与双重否定是肯定的意思差不多,八进制数\41转化为十进制是33,对应的ASCII码字符为!,其它字符没有转义字符,就直接打印出来

        7.转义字符\a:警告字符,蜂鸣

#include<stdio.h>
int main()
{
	printf("\a");
	return 0;
}

         打印的时候会响一声“叮咚”

        8.转义字符\b:退格符

#include<stdio.h>
int main()
{
	printf("abcdef\b\b\b\b");
	return 0;
}

打印结果:

         \b表示向后退格,退到相应位置时,相应的字符将无法打印,在退格的时候有叠加效果,如上代码中一共输入4个\b,相应向后退4格,在输入的abcdef中倒数第四位c将无法打印

        9.转义字符\f:换页,将当前位置移到下一页的开头,在使用打印机时会直接换页,在编译器中表现不明显

        10.转义字符\v:垂直制表符,也用于打印时

        11.转义字符\r:回车,将当前位置移到本行的开头,并覆盖打印

#include<stdio.h>
int main()
{
	printf("abcdef\r");
	return 0;
}

打印结果:

        5.3 注释:1. 代码中有不需要的代码可以直接删除,也可以注释掉

                        2. 代码中有些代码比较难懂,可以加一下注释文字

        注释有两种风格:

                        C语言风格的注释
/*xxxxxx*/

                        缺陷:不能嵌套注释

                        C++风格的注释
//xxxxxxxx

                        可以注释一行也可以注释多行

以使用函数计算两个数的和为例:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

int Add(int x, int y)
{
	return x + y;
}
/*C语言风格注释
int Sub(int x, int y)
{
    return x-y;
}
*/
int main()
{
	int a = 0;
	int b = 0;					//C++注释风格
	scanf("%d%d", &a, &b);		//用scanf取a,b的地址,能够随机赋值计算
	printf("sum=%d\n", Add(a, b));  //调用Add函数,完成加法
	return 0;
}

打印结果:

 

六、 选择语句:用if语句、switch case语句实现

        如果好好学习,就能找到好工作

        如果不学习,找不到好工作

        这就是选择!

例如用if语句实现:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
int main()
{
	int num = 0;
	printf("学习编程\n");
	printf("你能够坚持吗?(0不能/1能)");//>:为提示符
	scanf("%d", &num);
	if (1==num)
		printf("好工作,高薪资");
	else
		printf("平淡的生活");
	return 0;
}

七、循环语句:用while语句、for语句、do … while语句实现

        有些事必须一直做,比如学习,应该日复一日

例如用while实现连续输入1-100的数字:

#include<stdio.h>
int main()						//代码功能:输出1-100的数字
{
	int a = 1;
	//int b = 0;
	while (a < 101)
	{
		printf(" %d", a );
		a += 1;			
	}
	return 0;
}

打印结果:

 八、函数:是简化代码,代码复用。

        8.1 库函数:当我们描述的基础功能,它们不是业务性的代码。我们在开发的过程中每个程序员都可能用的到,为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。如:

        1. 我们知道在我们学习
C
语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想 把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格 式打印到屏幕上(printf
)。

        2. 在编程的过程中我们会频繁的做一些字符串的拷贝工作(
strcpy
)。

        3. 在编程是我们也计算,总是会计算
n

k
次方这样的运算(
pow
)。

        如果想了解更多C语言的更多库函数可以去C++官网查看:

        C++官网(英文版):
cppreference.com

        
C++官网(中文版):
cppreference.com

        也可去:
cplusplus.com – The C++ Resources Network

对库函数简单的分类:

                                       
1. IO函数

                                        2.字符串操作函数

                                        3.字符操作函数

                                        4.内存操作函数

                                        5.时间/日期函数

                                        6.数学函数

                                        7.其他库函数


:但是库函数必须知道的一个秘密就是:使用库函数,必须包含
#include
对应的头文件。

        8.2 自定义函数:如果库函数能干所有的事情,那就不需要程序员了, 所有更加重要的是自定义函数自定义函数和库函数一样,有函数名,返回值类型和函数参数。 但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间。

例如计算两个数的和:

#include <stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = num1 + num2;
    printf("sum = %d\n", sum);
    return 0; 
}

利用函数计算两个数的和:

#include <stdio.h>
int Add(int x, int y) 
{
   int z = x+y;
   return z; 
}
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = Add(num1, num2);
    printf("sum = %d\n", sum);
    return 0;
}

        直接调用自己定义的函数int Add(int x, int y),就不需要重复的去敲代码,需要求两个数的和时直接调用函数就行了。

九、数组

        9.1 定义:一组相同类型元素的集合

                例:要存储1-10的数字,怎么存储?

int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素

       
 9.2 数组的下标:
C
语言规定,数组的每个元素都有一个下标,下标是从
0
开始的。

数组可以通过下标来访问的。

                

int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//如果数组10个元素,下标的范围是0-9

数组中各值对应的下标:

打印数组里面的数值:

#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;
 }

 打印结果:

 十、操作符:算术操作符、移位操作符、位操作符、赋值操作符

        10.1 算术操作符:+        –        *(乘号)        /(除号)        %(取余)

        1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
        2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
        3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
	int a = 0;
	int b = 1;        //对b赋的初始值不能为0,因为在后面要作为除数
	int c = (-8 + 22) * a - 10 + b / 2;
	int d = a % b;
	scanf("%d%d", &a, &b);
	printf("计算结果=%d\n", c);
	printf("取余=%d\n", d);
	return 0;
}

打印结果:

         10.2 移位操作符:        <<左移操作符        >>右移操作符

        1.移位操作符的操作数只能是整数
        2.针对的是十进制转化为二进制后,对二进制的数值进行移位,
        3.左移操作符,左边舍去右边补零
        4.对于移位运算符,不要移动负数位,这个是标准未定义的

int main()
{
	int a = 1;//int型有4个字节32个比特位转化为二进制00000000000000000000000000000001  转化为十进制就为1
	int b=a << 2;                               //00000000000000000000000000000100  转化为十进制就为4
    int b=a<<-1;//错误的移位
	printf("%d", b);
	return 0;
}

打印结果:

        移位操作符是针对二进制数进行移位,例如上述代码中int类型4个字节=4×8=32位,将对应的整数先转化为32位的二进制数,在对二进制数进行移位,移位遵循——左移操作符时,左边舍去右边补零;右移操作符时,右边舍去左边补零。最后再将移位后的二进制数转化为十进制数打印出来。

        10.3 位操作符:     &按位与    |按位或    ^按位异或(均是对二进制进行)

#include<stdio.h>

int main()
{
	int a = 1;			//0001
	int b = 2;			//0010
	printf("%d\n", a & b);			//0000
	printf("%d\n", a | b);			//0011
	printf("%d\n", a ^ b);			//0011     相同为0不同为1
	return 0;
}

打印结果:

         10.4 赋值操作符:=        +=         -=         *=         /=         &=         ^=          |=            >>=   <<=                

        赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。

       
10.5 单目操作符:

操作符 作用

逻辑反操作

负值
+ 正值
& 取地址
sizeof 操作数类型长度(以字节为单位)
~ 对一个数的二进制按位取反
前置、后置–
++ 前置、后置++
* 间接访问操作费(解引用操作法)
(类型) 强制类型转换

                前五个操作符在前面已经介绍了,我向大家介绍后面五种就行

        1.对一个数的二进制按位取反~:~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0,例:十六进制9对应:0x00000009   当取反时~9对应:0xfffffff6

#include<stdio.h>
main()
{
	int a = 0;
	printf("%x", ~a);
}

打印结果:

        2.前置、后置++:前置++作用是先进行运算再赋值,而后置++为先先复制后运算

前置++:

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

打印结果:

         代码中我们先给 i 一个初始值2,用b来反应 i 最终的值。前置++是先对2进行+1运算,然后将加上1后的值3赋给变量a,故a的值为3,经过运算和赋值后 i 的值变为3,故将i变化后的值3赋给b,故b的值为3

后置++:

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

打印结果:

         代码中我们先给 i 一个初始值2,用b来反映 i 最终的值。后置++是先 i 的值2先赋给a,然后对 i 加1,则a的值为2,经过赋值和运算后 i 的值变为3,故将 i 变化后的值3赋给b,故b的值为3。

        3.前置、后置–:

前置–:

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

打印结果:

         代码中我们先给 i 一个初始值2,用b来反映 i 最终的值。前置–是先对2进行-1运算,然后将减去1后的值1赋给变量a,故a的值为1,经过运算和赋值后 i 的值变为1,故将 i 变化后的值1赋给b,故b的值为1

后置–:

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

打印结果:

        代码中我们先给 i 一个初始值2,用b来反映 i 最终的值。后置–是先 i 的值2先赋给a,然后对 i 减1,则a的值为2,经过赋值和运算后 i 的值变为1,故将 i 变化后的值1赋给b,故b的值为1。

        4.间接访问操作费(解引用操作法) *:该操作符常用于指针

#include<stdio.h>
int main()
{
	int a = 10;
	int* p= &a;
	*p =20;
	printf("%d\n", a);
	return 0;
}

 打印结果:

         想要了解此代码需要先了解指针的概念,可先往下翻,初步了解指针。代码中*p=20;其中的*就是解引用操作符,意思是通过p中存放的地址,找到p所指向的对象,而*p就是p所指向的对象,其代表的就是变量a。

        5.强制类型转换(类型):

#include<stdio.h>
int main()
{
	double a = 3.14;
	printf("%d\n", (int)a);
	return 0;
}

打印结果:

         原本定义的变量是double型,在(类型)的强制转换下,将变量a转换为int类型,使用该操作符时,将需呀转化的类型放入括号内,将需要转化的变量紧放其后切只对一个变量有效,如果在()后有两个变量,则只对紧跟的第一个变量有效该转换只能在该语句生效,并且在其他地方,变量a仍然是double类型。

       
10.6 关系操作符:

> 大于
>= 大于等于
< 小于
<= 小于等于
!= 用来测试“不相等”
== 用来测试“相等”

       
10.7 逻辑操作符:

&& 逻辑与
|| 逻辑或

       
10.8 条件操作符:
exp1
?
exp2
:
exp3

       
10.9 逗号表达式:
exp1
,
exp2
,
exp3,……expN

     
  10.10. 下标引用、函数调用和结构成员:        
[]         ()         .         
->

十一、常见关键字:C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。

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

十二、#define 定义常量和宏

       
12.1 #define 定义常量

#include(stdio.h)
#define c 100
int main()
{
	printf("%d\n", c);
	int d = 100;
	printf("%d", d);
	return 0;
}

打印结果:

         12.2 #define 定义宏:

#include<stdio.h>
#define add(x,y)(x)+(y)    //宏名  参数 宏体
int main()
{
	int a = 10;
	int b = 20;
	int c = add(a, b);    //替换成int c=((a)+(b))
	printf("%d", c);
	return 0;
}

打印结果:

 十三、 指针

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

        内存单元有相对应的编号,这一个编号就是地址,这个地址也叫做指针,也就是说地址就是指针,用来储存地址的变量叫指针变量。

        如何取出变量的地址呢?就要用到前面介绍的取地址符&

#include <stdio.h>
int main()
{
 int num = 10;
 &num;//取出num的地址。注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
 printf("%p\n", &num);//打印地址,%p是以地址的形式打印
 return 0;
 }

        &num的作用就是取出创建的变量num的地址

内存
一个字节 0xFFFFFFFF
一个字节 0xFFFFFFFE
一个字节 0xFFFFFFFD
0x0012FF47
0x0012FF46
0x0012FF45
0x0012FF44
一个字节 0x00000002
一个字节 0x00000001
一个字节 0x00000000

        变量num的类型是int类型,其大小为4个字节,红色的部分为num的地址,打印的地址就是读取到num的第一个地址。

        变量取出来后如果需要储存,就需要定义指针变量:

int num = 10;
int* p=&num;            //int说明指针变量p所指的变量num是一个整形

指针的具体使用:

#include<stdio.h>
int main()
{
	int a = 10;
	int* p= &a;
	*p =20;
	printf("%d\n", a);
	return 0;
}

打印结果:

        定义一个整型的变量a=10,用&a取出变量a的地址并放入指针变量p中,指针变量p的类型(也就是a的类型)是整型,用解引用符找到p变量的指向对象(a),并对指向对象重新赋值20,打印a的结果时发现打印的就是第二次赋值的20。

       
13.2 指针变量的大小,用到前面所介绍的sizeof

#include<stdio.h>
int main()
{
    printf("%d\n", sizeof(char *));
    printf("%d\n", sizeof(short *));
    printf("%d\n", sizeof(int *));
    printf("%d\n", sizeof(double *));
    return 0; 
}

打印结果:

         结论:指针大小在32位平台是4个字节,64位平台是8个字节。

十四、结构体:结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。

比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。 这里只能使用结构体来描述了,具体就是把单一的类型组合在一起。

#include<stdio.h>
struct xs				//定义结构体类型要用struct,这个类型名叫xs(自己定义)
{
	char name[20];   //叫做结构体成员,其中要放的是字符串,需要将字符串放到字符串数组里面  
	int age ;
	char sex[10];
	char id[15];
};
void project(struct xs* dy)   //自定义函数project,将s的地址赋给dy,*dy表示的是s
{
	printf("%s %d %s %s\n", (*dy).name, (*dy).age, (*dy).sex, (*dy).id);			
	printf("%s %d %s %s\n", dy->name, dy->age, dy->sex, dy->id);
}
int main()
{
	struct xs s = { "张三", 21 ," 男 ","20209999" };//s为创建的结构体变量,访问其对象时,需要加.这个操作符
	printf("%s %d %s %s\n", s.name, s.age, s.sex, s.id);
	project(&s);           //自定义函数,取s的地址给自定义的函数
	return 0;
}

打印结果:

         上面展示了结构体的三种打印方式,其中放在project()函数里面的是利用指针打印,外面的那一种是直接打印不用创建指针。在函数内的打印方式和外面的那一种差别不大。

函数外:打印时填入需要打印的类型,最后在后面写上   结构体变量(s).字符串的变量名(name、age、sex、id)   这种格式打印

函数内:将结构体变量名用指针来代替,只是改变的形式,但没改变本质,最后将操作符“.”改成  “->”就行

物联沃分享整理
物联沃-IOTWORD物联网 » 探索C语言的奥秘:从初识开始

发表评论