C指针原理教程之C快速入门

一、C简介

1、C语言简介

C语言是一门语法 精简的语言,它的关键字仅有32个,C语言以main函数为主函数,程序编译运行后后,执行的就是main函数的内容,因此,纵观很多C语言程序,形成了一道有趣的风景线:头文件和许多c代码文件以main函数为中心和起始点构造,在main函数中调用了这些文件中编写的代码,引用头文件。C语言程序实质就是在程序中调用 C标准库提供的函数、其它C库提供的函数、操作系统提供的API接口、自己定义的函数,同时应用适当的数据结构和算法来完成工作。

C语言虽然精简,但却很强大,它不但能完成比它更复杂的程序语言所做的事情,而且还能做其他语言不擅长的工作,比如操作系统,LINUX、UNIX的内核、gnome桌面等等都是C语言的杰作,尤其在系统内核的设计与研发领域,它的“兄弟”C++也不是对手(至今为止,没有出现一款用C++制作的桌面系统或嵌入式系统的内核)。

2、C语言的关键字

auto :声明自动变量   
short :声明短整型变量或函数   
int: 声明整型变量或函数
long :声明长整型变量或函数   
float:声明浮点型变量或函数   
double :声明双精度变量或函数   
char :声明字符型变量或函数   
struct:声明结构体变量或函数   
union:声明共用数据类型   
enum :声明枚举类型   
typedef:用以给数据类型取别名   
const :声明只读变量   
unsigned:声明无符号类型变量或函数   
signed:声明有符号类型变量或函数   
extern:声明变量是在其他文件正声明   
register:声明寄存器变量   
static :声明静态变量   
volatile:说明变量在程序执行中可被隐含地改变   
void :声明函数无返回值或无参数,声明无类型指针   
if:条件语句   
else :条件语句否定分支(与 if 连用)   
switch :用于开关语句   case:开关语句分支   
for:一种循环语句   
do :循环语句的循环体   
while :循环语句的循环条件   
goto:无条件跳转语句   
continue:结束当前循环,开始下一轮循环   
break:跳出当前循环   
default:开关语句中的“其他”分支   
sizeof:计算数据类型长度   
return :子程序返回语句(可以带参数,也可不带参数)循环条件

猜数字:

我们来一步步打造一个猜数字的游戏

游戏的大意是:输入一个1-500以内的正整数,程序根据玩家输入的数字,提示数字比正确答案之前大,或者数字比正确答案之间小,比如要猜的数字是85,玩家第一次输入90,提示比要猜的数字大,第二次输入80,提示比要猜的数字小,第二次输入85,提示猜中了。

下面来一步步打造这个游戏,帮助大家快速复习C语言基础知识。

(1)编写输入数字的代码,并编译执行。

dp@dp:~/cquick % cat guessnum.c

#include <stdio.h>

int main(){

int mynum;

printf("你好,请输入一个数字:");

    scanf("%d",&mynum);

printf("\n你输入的数字是:%d\n",mynum);

}

接着在终端编译执行:

dp@dp:~/cquick % gcc guessnum.c -o myguess

dp@dp:~/cquick % ./myguess

你好,请输入一个数字:55

你输入的数字是:55

dp@dp:~/cquick %

纵观上面程序及其执行结果,可发现,C语言中可使用printf函数完成屏幕输出,可使用scanf函数接受指定格式的数据录入,此外,”\n”表示换行符,”%d”表示整数格式。

(2)限制输入数字的范围

游戏的要求是1-500以内的整数

但是如果我们在上述程序中输入900、-10等不符合要求的数字,仍然能通过,

你好,请输入一个数字:900

你输入的数字是:900

你好,请输入一个数字:-10

你输入的数字是:-10

系统没有提示错误。因此,需要修改程序限制玩家输入数字的范围

#include <stdio.h>

int main(){

    int mynum;

    printf("你好,请输入一个数字:");

    scanf("%d",&mynum);

    if (mynum>500 ||mynum<1){

        printf("数字仅限于1-500之间,请重新运行本程序!\n");

    }

    else{

    printf("\n你输入的数字是:%d\n",mynum);

    }

}

运行程序:

dp@dp:~/cquick % gcc guessnum.c -o myguess

dp@dp:~/cquick % ./myguess

你好,请输入一个数字:200

你输入的数字是:200

dp@dp:~/cquick % ./myguess

你好,请输入一个数字:900

数字仅限于1-500之间,请重新运行本程序!

dp@dp:~/cquick %

上面程序使用了C语言的if...else...语句块,这是一个很多语言都有的机制(包括一些函数语言,比如haskell的if...then...else....),该语句块分2个部分,第1个部分if语句段,表示如果if后面跟的条件满足的话,执行if语句段,第2个部分是else语句段,如果if后的条件不满足执行,什么是条件满足与不满足,C语言可理解为如果条件的返回值非0表示条件满足,如果是0则表示条件不满足。

可以将多个条件组合成一个综合条件做为该语句块的条件,方式是使用||(表示或者)或&&(表示并且),比如上面程序中的条件:mynum>500 ||mynum<1

但是C语言中有一个关键字NULL,在C语言中,条件语句中出现的NULL和0的值是一样的,但NULL常用于指针和对象,0常用于int等整型数。这意味着,如果出现了下面类似的语句块,就意味着是对含有指针变量(指针变量通常用于指向其它变量的内存地址,比如下面代码中的mypoint1和mypoint2)的条件进行判断了:

if (mypoint1!=NULL){

............

}

if (mypoint2==NULL){

............

}

从运行效果来看,错误的数字没有被接受,但要想重新输入,必须重新运行一次程序。

(3)引入循环机制

C语言中可以使用while循环,语法格式如下:

while(条件){

语句块

}

或者使用do...while循环,语法格式如下:

do{

语句块

}while (条件)

通过循环,在玩家输入错误数字的情况下,给玩家重新输入的机会,而不是直接退出程序。

dp@dp:~/cquick % cat guessnum.c

#include <stdio.h>

int main(){

int mynum;

int ispass=0;

while (!ispass){

printf("你好,请输入一个数字:");

    scanf("%d",&mynum);

if (mynum>500 ||mynum<1){

ispass=0;

printf("数字仅限于1-500之间,请重新运行本程序!\n");

}

else{

ispass=1;

printf("\n你输入的数字是:%d\n",mynum);

}

}

}

编译并运行:

dp@dp:~/cquick % gcc guessnum.c -o myguess

dp@dp:~/cquick % ./myguess

你好,请输入一个数字:1234

数字仅限于1-500之间,请重新运行本程序!

你好,请输入一个数字:-12

数字仅限于1-500之间,请重新运行本程序!

你好,请输入一个数字:88

你输入的数字是:88

上述程序中的while的条件中使用了“!”,它表示逻辑非。

也可以用do...while来实现它:

#include <stdio.h>

int main(){

    int mynum;

    int ispass=0;

    do{

    printf("你好,请输入一个数字:");

    scanf("%d",&mynum);

    if (mynum>500 ||mynum<1){

        ispass=0;

        printf("数字仅限于1-500之间,请重新运行本程序!\n");

    }

    else{

        ispass=1;

        printf("\n你输入的数字是:%d\n",mynum);

    }

    } while (!ispass);

}
dp@dp:~/cquick % gcc guessnum.c -o myguess

dp@dp:~/cquick % ./myguess

你好,请输入一个数字:8889

数字仅限于1-500之间,请重新运行本程序!

你好,请输入一个数字:12

你输入的数字是:12

观察上面2个程序可看出,使用了ispass这个变量做为是否退出循环的依据,也可以不使用ispass,直接通过break语句退出循环(注意,只能退出break语句本身所在的那层循环),

#include <stdio.h>

int main(){

    int mynum;

    int ispass=0;

    while(1){

    printf("你好,请输入一个数字:");

    scanf("%d",&mynum);

    if (mynum>500 ||mynum<1){

        printf("数字仅限于1-500之间,请重新运行本程序!\n");

    }

    else{

        printf("\n你输入的数字是:%d\n",mynum);

        break;

    }

    } 

}
dp@dp:~/cquick % gcc guessnum.c -o myguess

dp@dp:~/cquick % ./myguess

你好,请输入一个数字:8788

数字仅限于1-500之间,请重新运行本程序!

你好,请输入一个数字:66

你输入的数字是:66

dp@dp:~/cquick %
(0)

相关推荐

  • C指针原理教程之Ncurses介绍

    1.安装Ncurses Ncurses是一个能提供功能键定义(快捷键),屏幕绘制以及基于文本终端的图形互动功能的动态库. Ncurses是一个能提供基于文本终端窗口功能的动态库. Ncurses可以: · 只要您喜欢,您可以使用整个屏幕 · 创建和管理一个窗口 · 使用8种不同的彩色 · 为您的程序提供鼠标支持 · 使用键盘上的功能键 Ubuntu下 mysea@mysea-desktop:~$ sudo apt-get install libncurses5-dbg libncurses5-d

  • C指针原理教程之C内嵌汇编

    内联汇编的重要性体现在它能够灵活操作,而且可以使其输出通过 C 变量显示出来.因为它具有这种能力,所以 "asm" 可以用作汇编指令和包含它的 C 程序之间的接口.简单得说,内联汇编,就是可以让程序员在C语言中直接嵌入汇编代码,并与汇编代码交互C程序中的C表达式,享受汇编的高运行效率. 内联汇编的格式是直接在C代码中插入以下格式: asm( .... .... ) 其中的"..."为汇编代码,比如下面例子中,在 result=a*b和printf("%d\

  • C指针原理教程之AT&T汇编

    汇编在LINUX系统下的意义远远大于WINDOWS系统,LINUX内核部分代码就是汇编编写的.然后,绝大多数 Linux 程序员以前只接触过DOS/Windows 下的汇编语言,这些汇编代码都是 Intel 风格的.但在 Unix 和 Linux 系统中,更多采用的还是 AT&T 格式,两者在语法格式上有着很大的不同,因此应对AT&T汇编应有一个基本的了解和熟悉. 我们在LINUX下用C编写一段最简单的helloworld程序,命令为hello.c #include <stdio.h

  • C指针原理教程之编译原理-小型计算器实现

    1.打开cygwin,进入home目录,home目录在WINDOWS系统的cygwin安装目录映射为home目录. 2.首先,在home目录中新建文件夹,在文件夹中放置如下内容的test1.l /*统计字数*/ %{ int chars=0; int words=0; int lines=0; %} %% [a-zA-Z]+ {words++;chars+=strlen(yytext);} \n {chars++;lines++;} . {chars++;} %% main(int argc,c

  • C指针原理教程之C指针基础

    tcctok.h定义了C语言的词法分析的基本元素,主要定义了关键字. / keywords /      DEF(TOK_INT, "int")      DEF(TOK_VOID, "void")      DEF(TOK_CHAR, "char")      DEF(TOK_IF, "if")      DEF(TOK_ELSE, "else")      DEF(TOK_WHILE, "wh

  • C指针原理教程之垃圾回收-内存泄露

    一.内存泄露 1.正常的链表操作 下面程序建立一个10元素的链表,输出它们的节点,每个节点是一个员工的工号和年龄.最后删除每个节点,释放列表. dp@dp:~/memorytest % cat 1.c #include <stdlib.h> #include <stdio.h> //code:myhaspl@myhaspl.com //author:myhaspl //date:2014-01-10 typedef struct listnode mynode; struct li

  • C指针原理教程之语法树及其实现

    下面完成一个简单的计算器通过语法树进行计算,首先定义一个语法树的结构,然后编写flex文件,解析数字或符号,对于 符号返回本身,对于数字,返回NUMBER,并对yylval的d进行赋值,yylval指向一个联合类型,接着,在语法分析器中完成语法树的节点的增加,分别对应数字和符号有不同的增加方式,最后有一个单独的C代码处理计算,以及语法树相关计算的函数.对结果的计算的方式是对语法树进行递归. 词法分析器为: dp@dp:~/flexbison % cat myast.l %option noyyw

  • C指针原理教程之C快速入门

    一.C简介 1.C语言简介 C语言是一门语法 精简的语言,它的关键字仅有32个,C语言以main函数为主函数,程序编译运行后后,执行的就是main函数的内容,因此,纵观很多C语言程序,形成了一道有趣的风景线:头文件和许多c代码文件以main函数为中心和起始点构造,在main函数中调用了这些文件中编写的代码,引用头文件.C语言程序实质就是在程序中调用 C标准库提供的函数.其它C库提供的函数.操作系统提供的API接口.自己定义的函数,同时应用适当的数据结构和算法来完成工作. C语言虽然精简,但却很强

  • tensorflow2.0教程之Keras快速入门

    Keras 是一个用于构建和训练深度学习模型的高阶 API.它可用于快速设计原型.高级研究和生产. keras的3个优点: 方便用户使用.模块化和可组合.易于扩展 1.导入tf.keras tensorflow2推荐使用keras构建网络,常见的神经网络都包含在keras.layer中(最新的tf.keras的版本可能和keras不同) import tensorflow as tf from tensorflow.keras import layers print(tf.__version__

  • Go语言快速入门指针Map使用示例教程

    目录 1. 指针 1.1 指针地址和指针类型 1.2 指针取值 1.3 空指针 1.4 new 的使用 1.5 new与make的区别 2. Map 2.1 什么是Map key,value存储 hash冲突 hash冲突的常见解决方法 开放定址(线性探测)和拉链的优缺点 2.2 Map 定义 2.3 map基本使用 2.4 map的遍历 2.5 map判断某个键是否存在 2.6 map使用delete()函数删除键值对 1. 指针 区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,

  • 30分钟快速入门掌握ES6/ES2015的核心内容(上)

    前言 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. 虽然目前并不是所有浏览器都能兼容ES6全部特性,但越来越多的程序员在实际项目当中已经开始使用ES6了.所以就算你现在不打算使用ES6,但为了看懂别人的你也该懂点ES6的语法了... 在我们正式讲解ES6语法之前,我们得先了解下Babel. Babel Babel是一个广泛使用的ES6转码器,

  • OpenStack云计算快速入门教程(1)之OpenStack及其构成简介

    该教程基于Ubuntu12.04版,它将帮助读者建立起一份OpenStack最小化安装.我是五岳之巅,翻译中多采用意译法,所以个别词与原版有出入,请大家谅解.我不是英语专业,我觉着搞技术最重要的就是理解,而不是四级和考研中那烦人的英译汉,所以我的目标是忠于原意.通俗表达,Over.英文原文在这里(http://docs.openstack.org/es@***/openstack-compute/starter/content/ ,请将ex@***中的@去掉,CU屏蔽的F词),下面步入正题: 第

  • 基于PHP的cURL快速入门教程 (小偷采集程序)

    最爽的是,PHP也支持 cURL 库.本文将介绍 cURL 的一些高级特性,以及在PHP中如何运用它. 为什么要用 cURL? 是的,我们可以通过其他办法获取网页内容.大多数时候,我因为想偷懒,都直接用简单的PHP函数: $content = file_get_contents("http://www.jb51.net");// or$lines = file("http://www.jb51.net");// orreadfile(http://www.jb51.

随机推荐