C语言的数据类型

本文详细介绍了C语言的数据类型,包括标识符书写、输入输出函数`scanf()`的使用、代码书写格式规范,以及字符类型、短整型与长整型、浮点型的特性和内存占用。还讲解了占位符匹配、`sizeof()`运算符、进制转换,并通过贪吃蛇小程序展示了实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 标识符的书写

  标识符采用如下两种方式书写:驼峰式,下划线式。

2 scanf()

  标准C函数有输入输出缓冲区,Linux的函数无此。当使用scanf读取,输入非法时,使用scanf(“%*[^\n]”);scanf(“%*c”);从而不影响对后面读取数据的影响.
特别注意运行时,scanf的输入格式,空空格,打不打逗号。

scanf.c
#include<stdio.h>
int main() {
    int num = 0, num1 = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    scanf("%*[^\n]");
    scanf("%*c");
    printf("请输入一个数字:");
    scanf("%d",&num1);
    printf("num是%d,num1是%d\n",num, num1);
    return 0;
}
inbuf.c

#include <stdio.h>
int main() {
    int num = 0;
    for (;;) {
        printf("请输入一个数字:");
        if (scanf("%d", &num)) {
            scanf("%*[^\n]");
            scanf("%*c");
            break;
        }
        else {
           scanf("%*[^\n]");
           scanf("%*c");
        }
        }
      printf("num是%d\n", num);
      return 0;
}

3 代码书写格式

一些需注意的代码格式:
关键字后面接空格,函数名后面不要空格
, ;不空格且向前靠拢
&&  ||  !=   ==   >=  <=   =  +  -  *  / 这些操作符前后都要空格
++   自减  []  .   -> 前后都不空格

4 字符类型

  字符类型是一种数据类型,其中包含了256个不同的字符。字符类型的名称是char,这种类型的数据使用两个单引号表示,例如‘a’表示字符a
  ASCII码表记录了字符和数字之间的对应关系
    ‘a’——97(0x61)
    ‘A’——65(0x41)
    ‘0’——-48
  所有字符分成两组,每组包含128个不同的字符,一组固定被转换成0到127之间的数字,另一组在某些计算机上被转换成-1到-128之间的数字,在另外一些计算机上被转换成128到255之间的数字
  字符类型数据最好不要当成数字使用
  unsigned char也是一种数据类型,表示无符号字符型,这种类型的数字范围固定从0到255,无符号字符类型数据可以当成数字使用
根据ASCII码表有如下结论:‘c’-‘a’=’C’-‘A’ ‘c’-‘a’=’2’-‘0’=2-0
  ‘\n’:换行符(表示前后内容分散在两个不同的行中)
  ‘\r’:回车符(表示后面的内容从行首开始)
  ‘\t’:制表符(保证后面的内容从某一段的开头开始输出)
  ‘\’:代表\
  ‘\”’:代表“
  ‘\”:代表‘

5 短整型与长整型

  短整数也是一种数据类型,它的名称是short,短整数类型一共包含65536个不同的整数,范围是从-32768到32767
  unsigned short是无符号短整数类型,无符号短整数类型的数字范围是从0到65536为止
  长整数也是一种数据类型,它的名称是long,long类型包含2的32次方个不同的数字,其中一半是负数,另一半是非负数
  unsigned long表示无符号长整数类型,数字范围是从0到2的32次方减一为止
  在我们使用的计算机和编译器环境下int和long是一样的

6 浮点型

单精度浮点类型是一种表示带小数点数字的数据类型,它的名字是float
双精度浮点类型也是一种数据类型,它的名字是double

程序中不带小数点的数字都被看成是int类型的数字
程序中在不带小数点的数字后面加一个u表示这个数字是unsigned int类型的
程序中带小数点的数字被看成是double类型的数字
程序中在带小数点的数字后面加上一个f表示这个数字是float类型的

7 占位符匹配关系

char—————%c
short————–%hd
unsigned short—–%hu
long—————%ld
unsigned long——%lu
int—————-%d
unsigned int——-%u
float————–%f或%g
double————-%lf或%lg
打印字符串——————%s
占位符特殊用法
%3d 数字占3个位置
%03d 数字占三个位置,空的位置用0补充
%-3d 占3个位置,数字从最左边的位置开始输出
%7.2f 一共占7个位置,小数点后占2个位置

打印地址用%p格式,是十六进制的

8 各数据类型占内存大小

计算机的内存被划分成很多字节,任意两个字节的大小一样
所有变量都是由一个或多个连续的字节构成的
char,unsigned char————-1个字节
short,unsigned short———–2个字节
long,unsigned long————-4个字节
int,unsigned int—————4个字节
float————————–4个字节
double————————-8个字节

9 sizeof()

sizeof关键字可以计算一个变量或某个数据类型占的字节个数
1、给出指定数据类型所占内存的字节,如果括号里是数据,则返回给定数据在内存中占用的字节数
sizeof(char)—–> 1
size(5)——>4
2、不会对括号内的表达式进行计算
例如:
int a=2;
printf(“%d\n”,sizeof(a++));//a=2
3、如果括号里有不同类型的数据,会按照数据类型最长的数据来进行返回。
sizeof(3+2.5)———->8

10二进制与其他进制间转换

  二进制是一种表示数字的方式,每个数位上是0或者是1,每个位置上的1代表的数字都是2的整数次方,最右边的位置编号为0,向左依次递增,编号为n的位置上的1对应的数字是2的n次方
每个字节可以划分成八个二进制位
二进制转换十进制
0110 0011=2^6+2^5+2^1+2^0=64+32+2+1=99
0101 1101=2^6+2^4+2^3+2^2+2^0=64+16+8+4+1=93
十进制转换二进制
71 ** ***1
35 0*** ***1
17 00** ***1
8 000* ***0
4 0000 ***0
2 0000 0**0
1 0000 00*1
0 0000 0000

0100 0111
除以2取余倒着写

另一种从十进制转二进制的方法
103=64+32+4+2+1 2^7=128 2^6=64

八进制也是一种表示数字的方式
01100010=01 100 010=0142 八进制数前面加0
占位符%o可以让输出为八进制

十六进制也是二进制的另外一种表示方式
01100010=0110 0010=0x62
a—-10 b—-11 c—-12 d—-13 e—-14 f—-15
十六进制打印的占位符是%x或%X

负数的二进制是相反数的二进制按位取反后加一的结果(补码)
按位取反加一的方法可以计算任何一个二进制数字的相反数,不管是正还是负
有符号数字的最左边二进制位叫做符号位,0表示正数,1表示负数
所有有符号类型的最小数的二进制都是左边一个1右边很多0
整数类型变量之间互相赋值,会保留原有二进制不变,但在新数据中的解释方式会改变,从大空间变到小空间,会丢掉部分,从小空间扩到大空间,多的位要取决于原数,原数若无符号,则多的位全为0,若有符号,则多的位取决于符号位

MinGW是windows操作系统里的gcc

11贪吃蛇小程序

//这里,附一个简单的用c写的贪吃蛇的程序,小蛇不能增长
snake.c
#include<stdio.h>
#include<time.h>
#include<stdbool.h>
#define APPLE           '@'
#define SNAKEHEAD       '+'
#define SNAKETAIL       '-'
#define SIZE            10

typedef struct {
    int row;
    int col;
}Pos;

typedef struct {
    Pos head;
    Pos tail;
}Snake;

Snake snake;
Pos apple;

bool is_same(const Pos* pFirstPos, const Pos* pSecondPos) {
    if ((pFirstPos->row == pSecondPos->row) && (pFirstPos->col == pSecondPos->col)) {
        return true;
    }
    else {
        return false;
    }
}

void init_snake() {
    int row = rand() % (SIZE - 2);
    int col = rand() % (SIZE - 2);
    int direction = rand() % 4;
    snake.head.row = row;
    snake.head.col = col;
    switch(direction) {
        case 0:
                //尾巴在头上边
                snake.tail.row = row - 1;
                snake.tail.col = col;
                break;
            case 1:
                //尾巴在头下面
                snake.tail.row = row + 1;
                snake.tail.col = col;
                break;
            case 2:
                //尾巴在头左边
                snake.tail.row = row;
                snake.tail.col = col - 1;
                break;
            default:
                //尾巴在头右边
                snake.tail.row = row;
                snake.tail.col = col + 1;
                break;
    }
}

void plant_apple() {
    do {
        apple.row = rand() % (SIZE - 2);
        apple.col = rand() % (SIZE - 2);
    } while ((is_same(&apple, &(snake.head))) || (is_same(&apple, &(snake.tail))));
}

void show_map() {
    /*这里的row和col变量是局部变量,虽然和前面的全局变量同名,但是,由于局部优先原则,局部的覆盖了全局的。*/
    int row = 0;
    int col = 0;
    for (row = 0; row < SIZE; row++) {
        for (col = 0; col < SIZE; col++) {
            if ((row == apple.row) && (col == apple.col)) {
                printf("%c",APPLE);
            }
            else if ((row == snake.head.row) && (col == snake.head.col)) {
                printf("%c",SNAKEHEAD);
            }
            else if ((row == snake.tail.row) && (col == snake.tail.col)) {
                    printf("%c",SNAKETAIL);
            }
            else {
                printf(" ");
            }
        }
        printf("\n");
    }
}

void move_snake() {
     /*这里direction和前面的一个direction都是局部变量,作用域不同,所以虽然同名,但互不影响*/
    char direction;
    int row = 0;
    int col = 0;
    printf("请输入移动的方向:(0表示向上,1表示向左,2表示向下,3表示向右)");
    scanf("%c", &direction);
    /*这里输入一个字符后还敲了回车键,这个也会进入到输入缓冲区中,所以下次你还没有输入,它就运行了*/
    scanf("%*[^\n]");
    scanf("%*c");
    //fflush(stdin);//这里刷新输入缓冲区没用,必须清空
    switch(direction) {
        case 'w':
            if ((snake.head.row - 1) >= 0) {
                snake.tail.row = snake.head.row;
                snake.tail.col = snake.head.col;
                snake.head.row--;
            }
            break;
        case 'a':
            if ((snake.head.col - 1) >= 0) {
                snake.tail.row = snake.head.row;
                snake.tail.col = snake.head.col;
                snake.head.col--;
            }
            break;
        case 's':
            if ((snake.head.row + 1) < SIZE){
                snake.tail.row = snake.head.row;
                snake.tail.col = snake.head.col;
                snake.head.row++;
            }
            break;
        default:
            if ((snake.head.col = 1) < SIZE) {
                snake.tail.row = snake.head.row;
                snake.tail.col = snake.head.col;
                snake.head.col++;
            }
            break;
    }
    if (is_same(&apple, &(snake.head)) || (is_same(&apple, &(snake.tail)))) {
        plant_apple();
    }
}

int main() {
    /*rand()产生的是伪随机数字,每次执行是相同的。若要不同,以不同的值来初始化它,初始化的函数是srand()*/
    /*time(0)可获得自1970年1月1日00:00:00以来的秒数*/
    srand(time(0));
    init_snake();
    plant_apple();
    while (1) {
        show_map();
        move_snake();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值