Skip to content
鼓励作者:欢迎打赏犒劳

c基础

数据类型

数据类型:c语言中数据类型有3种,分别是基本数据类型、构造数据类型、指针数据类型。

打印格式对应数据类型含义
%cchar字符型,输入的数字按照ASCII码相应转换为对应的字符
%hdshort int短整数
%huunsigned short无符号短整数
%dint接受整数值并将它表示为有符号的十进制整数
%uunsigned int无符号10进制整数
%ldlong接受长整数值并将它表示为有符号的十进制整数
%ffloat单精度浮点数
%lfdouble双精度浮点数
%e,%Edouble科学计数法表示的数,此处"e"的大小写代表在输出时用的"e"的大小写
%schar *字符串。输出字符串中的字符直至字符串中的空字符(字符串以'\0‘结尾,这个'\0'即空字符)
%pvoid *以16进制形式输出指针
%ounsigned int无符号8进制整数
%x,%Xunsigned int无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF

示例代码

c
#include <stdio.h>

int main() {
    // 1. 整数类型
    int integer = 123;
    printf("整数(int):%d\n", integer);
    
    // 2. 短整数类型
    short short_num = 321;
    printf("短整数(short):%hd\n", short_num);
    
    // 3. 长整数类型
    long long_num = 123456L;
    printf("长整数(long):%ld\n", long_num);
    
    // 4. 长长整数类型
    long long ll_num = 123456789LL;
    printf("长长整数(long long):%lld\n", ll_num);
    
    // 5. 无符号整数类型
    unsigned int uinteger = 456;
    printf("无符号整数(unsigned int):%u\n", uinteger);
    
    // 6. 浮点类型(单精度)
    float height = 1.77f;
    printf("浮点数(float):%f\n", height);
    printf("浮点数(科学计数法):%e\n", height);
    
    // 7. 双精度浮点类型
    double pi = 3.1415926535;
    printf("双精度浮点数(double):%lf\n", pi);
    printf("双精度浮点数(科学计数法):%le\n", pi);
    
    // 8. 字符类型
    char ch = 'A';
    printf("字符(char):%c\n", ch);
    printf("字符ASCII码:%d\n", ch);
    
    // 9. 字符串类型
    char str[] = "Hello C";
    printf("字符串(string):%s\n", str);
    
    // 10. 指针类型
    int *ptr = &integer;
    printf("指针地址(pointer):%p\n", ptr);
    
    // 11. 十六进制和八进制
    int num = 255;
    printf("十进制:%d\n", num);
    printf("十六进制(小写):%x\n", num);
    printf("十六进制(大写):%X\n", num);
    printf("八进制:%o\n", num);
    
    // 12. 科学计数法
    double sci_num = 123.456;
    printf("科学计数法:%e\n", sci_num);
    
    // 13. 格式控制示例
    double precise_num = 3.14159;
    printf("保留2位小数:%.2f\n", precise_num);
    printf("宽度控制(10位右对齐):%10d\n", integer);
    printf("宽度控制(左对齐):%-10d\n", integer);
    printf("补零显示:%05d\n", integer);
    
    return 0;
}

结果

text
整数(int):123
短整数(short):321
长整数(long):123456
长长整数(long long):123456789
无符号整数(unsigned int):456
浮点数(float):1.770000
浮点数(科学计数法):1.770000e+00
双精度浮点数(double):3.141593
双精度浮点数(科学计数法):3.141593e+00
字符(char):A
字符ASCII码:65
字符串(string):Hello C
指针地址(pointer):000000fb021ffc64
十进制:255
十六进制(小写):ff
十六进制(大写):FF
八进制:377
科学计数法:1.234560e+02
保留2位小数:3.14
宽度控制(10位右对齐):       123
宽度控制(左对齐):123       
补零显示:00123

系统变量

text
#include <stdio.h>
#include <float.h>
#include <limits.h>

int main() {
    printf("========== 整数类型限制 ==========\n");
    
    // char类型
    printf("char类型位数:%d 位\n", CHAR_BIT);
    printf("char最小值:%d\n", CHAR_MIN);
    printf("char最大值:%d\n", CHAR_MAX);
    printf("signed char最小值:%d\n", SCHAR_MIN);
    printf("signed char最大值:%d\n", SCHAR_MAX);
    printf("unsigned char最大值:%d\n\n", UCHAR_MAX);
    
    // short类型
    printf("short最小值:%d\n", SHRT_MIN);
    printf("short最大值:%d\n", SHRT_MAX);
    printf("unsigned short最大值:%u\n\n", USHRT_MAX);
    
    // int类型
    printf("int最小值:%d\n", INT_MIN);
    printf("int最大值:%d\n", INT_MAX);
    printf("unsigned int最大值:%u\n\n", UINT_MAX);
    
    // long类型
    printf("long最小值:%ld\n", LONG_MIN);
    printf("long最大值:%ld\n", LONG_MAX);
    printf("unsigned long最大值:%lu\n\n", ULONG_MAX);
    
    // long long类型(如果支持)
    #ifdef LLONG_MIN
    printf("long long最小值:%lld\n", LLONG_MIN);
    printf("long long最大值:%lld\n", LLONG_MAX);
    printf("unsigned long long最大值:%llu\n\n", ULLONG_MAX);
    #endif
    
    printf("========== 浮点类型限制 ==========\n");
    
    // float类型
    printf("float最小值:%e\n", FLT_MIN);
    printf("float最大值:%e\n", FLT_MAX);
    printf("float精度(有效位数):%d 位\n", FLT_DIG);
    printf("float最小精度:%e\n\n", FLT_EPSILON);
    
    // double类型
    printf("double最小值:%e\n", DBL_MIN);
    printf("double最大值:%e\n", DBL_MAX);
    printf("double精度(有效位数):%d 位\n", DBL_DIG);
    printf("double最小精度:%e\n\n", DBL_EPSILON);
    
    // long double类型
    printf("long double最小值:%Le\n", LDBL_MIN);
    printf("long double最大值:%Le\n", LDBL_MAX);
    printf("long double精度(有效位数):%d 位\n", LDBL_DIG);
    printf("long double最小精度:%Le\n\n", LDBL_EPSILON);
    
    printf("========== 其他限制 ==========\n");
    
    // 浮点数相关
    printf("float指数最小值:%d\n", FLT_MIN_EXP);
    printf("float指数最大值:%d\n", FLT_MAX_EXP);
    printf("float小数位数:%d\n", FLT_MANT_DIG);
    
    return 0;
}

结果

text
========== 整数类型限制 ==========
char类型位数:8 位
char最小值:-128
char最大值:127
signed char最小值:-128
signed char最大值:127
unsigned char最大值:255

short最小值:-32768
short最大值:32767
unsigned short最大值:65535

int最小值:-2147483648
int最大值:2147483647
unsigned int最大值:4294967295

long最小值:-2147483648
long最大值:2147483647
unsigned long最大值:4294967295

long long最小值:-9223372036854775808
long long最大值:9223372036854775807
unsigned long long最大值:18446744073709551615

========== 浮点类型限制 ==========
float最小值:1.175494e-38
float最大值:3.402823e+38
float精度(有效位数):6 位
float最小精度:1.192093e-07

double最小值:2.225074e-308
double最大值:1.797693e+308
double精度(有效位数):15 位
double最小精度:2.220446e-16

long double最小值:3.362103e-4932
long double最大值:1.189731e+4932
long double精度(有效位数):18 位
long double最小精度:1.084202e-19

========== 其他限制 ==========
float指数最小值:-125
float指数最大值:128
float小数位数:24

位运算符

常见的位运算符号有&、|、^、~、>>、<<,分别代表着如下含义:

运算符术语示例结果
&按位与运算011 & 1012个都为1才为1,结果为001
|按位或运算011 | 101有1个为1就为1,结果为111
^按位异或运算011 ^ 101不同的为1,结果为110
~取反运算~011100
<<左移运算1010 << 110100
>>右移运算1010 >> 10101
ps:取反、左右位移运算需要在补码的基础上运算。

& (与运算)

按位与(&)运算:位与位进行比较,如果都为1,则为1,否则为0;

text
/**
     * 按位与(&)运算:位与位进行比较,如果都为1,则为1,否则为0;
     * 示例:
     *      40    &     15    =     8
     *      0010 1000 
     *    & 0000 1111 
     * -------------------
     *      0000 1000
     */
printf("40 & 15 = %d\n", 40 & 15);

| (或运算)

按位或(|)运算:位与位进行比较,如果都为0,则为0,否则全为1;

text
/**
     * 按位或(|)运算:位与位进行比较,如果都为0,则为0,否则为1;
     * 示例:
     *      40    |     15    =     47
     *      0010 1000 
     *    | 0000 1111
     * ----------------
     *      0010 1111
     */
printf("40 | 15 = %d\n", 40 | 15);

^ (异或运算)

按位异或运算:位与位进行比较,不同为1,相同为0;

text
/**
     * 按位异或运算:位与位进行比较,相同为0,不同为1;
     * 示例:
     *      40    ^     15    =     39
     *      0010 1000 
     *    ^ 0000 1111 
     * ------------------
     *      0010 0111
     */
printf("40 ^ 15 = %d\n", 40 ^ 15);

~ (取反运算)

按位取反运算:补码取反,再将取反后的补码转为原码;

ps:无符号的数据,取反后最高位为1,也不需要逆运算。

text
/**
 * 按位取反运算:补码取反,再将取反后的补码转为原码。
 *      1、正数取反:由于正数的原码和补码是相同的,取反的方式简便了些。
 *              补码(原码) -> 取反 -> 补码逆运算 -> 反码逆运算(符号位不变) -> 取反后的原码
 *      2、负数取反:
 *              原码 -> 反码 -> 补码 -> 取反 -> 取反后的补码即原码
 * 示例:
 *            原码(补码)  取反的补码   补码逆运算-1  反码逆运算
 *      ~40 = 0010 1000 -> 1101 0111 -> 1101 0110 -> 1010 1001 = -41
 *
 *            原码(补码)  取反的补码   补码逆运算-1  反码逆运算
 *      ~15 = 0000 1111 -> 1111 0000 -> 1110 1111 -> 1001 0000 = -16
 *
 *                原码         反码          补码          取反
 *      ~-15 = 1000 1111 -> 1111 0000 -> 1111 0001 -> 0000 1110 = 14
 */
printf("~40 = %d\n", ~40);
printf("~15 = %d\n", ~15);
printf("~-15 = %d\n", ~(-15));

<< (左移运算符)

将数字的二进制补码全部向左移动,空出来的位置补0,超出范围的二进制数丢弃;
有符号的数据左移后最高位如果为1,则需要进行逆运算;
注意事项:

  • 无符号的数据,左移后最高位为1,也不需要逆运算;
  • -128:1000 0000 特殊情况也不需要逆运算;
text
/**
     * 示例:
     *      40 << 4 = 0010 1000 << 4 = 1000 0000 = -128 (特殊的不需要逆运算)
     *      41 << 4 = 0010 1001 << 4 = 1001 0000 = 1000 1111 = 1111 0000 = -112
     *       7 6 5 4 3 2 1 0
     *       1 0 0 1 0 0 0 0
     */

    int8_t p = 40;
    p <<= 4;    //  p = p << 4;
    printf("40 << 4 = %d\n", p);

>> (右移运算符)

将数字的二进制补码全部向右移动,空出来的位置补什么,取决于原来的最高位是什么。原来的最高是1就补1, 原来的最高位是0 就补0 。也可以转化成这样的一句话: 正数补0, 负数补1;

text
	
	/*
	  23: 
      0001 0111【原码】
      0001 0111【反码】 
      0001 0111【补码】 >> 2
	  -----------------
	  0000 0101【补码】 --->  5
	 */
	printf(" 23 >> 2 = %d \n" , 23 >> 2) ; 
	
	
	/*
	  -23: 
      1001 0111【原码】
      1110 1000【反码】
      1110 1001【补码】 >> 2
	  -----------------------------------------------
	  1111 1010【补码】 ->  1111 1001【反码】-> 1000 0110 【原码】 ==> -6
	 */
	printf(" -23 >> 2 = %d \n" , -23 >> 2) ;

示例代码:

text
#include <stdio.h>
#include <inttypes.h>

int main() {
    uint8_t a = 3;          // 0000 0011
    uint8_t b = 10;         // 0000 1010
    // 打印显示2个字符,个数不够,左边补0
    printf("%02x\n", a & b); // 0000 0010,16进制为02
    printf("%02x\n", a | b); // 0000 1011,16进制为0b
    printf("%02x\n", a ^ b); // 0000 1001,16进制为09

    uint8_t c = 10;          // 0000 1010
    uint8_t temp = ~c;       // 1111 0101
    printf("%02x\n", temp);   // 1111 0101,16进制为f5
    printf("%02x\n", c << 1); // 0001 0100,16进制为14
    printf("%02x\n", c >> 1); // 0000 0101,16进制为05

    return 0;
}

运行结果:

text
02
0b
09
f5
14
05

条件分支

if...else

text
#include <stdio.h>

int main() {
    // 定义一个整数变量记录年龄
    int age;
    printf("请输入年龄:");
    scanf("%d", &age);
    // 判断是否满 18 岁 (>=)
    if (age >= 18) {
        // 如果满 18 岁,允许进网吧嗨皮
        printf("允许进网吧嗨皮\n");
    } else {
        // 否则,提示回家写作业
        printf("回家写作业\n");
    }

    return 0;
}

switch

text
#include <stdio.h>

int main() {
    // 1. 定义变量保存数据
    int i;
    // 2. 输入数据
    printf("请输入1~7的数字:");
    scanf("%d", &i);
    // 3. 使用switch根据数据不同输出不同的结果
    switch (i) {
        case 1:
            printf("Monday\n");
            break;
        case 2:
            printf("Tuesday\n");
            break;
        case 3:
            printf("Wednesday\n");
            break;
        case 4:
            printf("Thursday\n");
            break;
        case 5:
            printf("Friday\n");
            break;
        case 6:
            printf("Saturday\n");
            break;
        case 7:
            printf("Sunday\n");
            break;
        default:
            printf("error\n");
    }

    return 0;
}

循环语句

while

text
#include <stdio.h>

int main() {
    // 需求跑步5圈
    // 1. 条件变量的定义
    int i = 1;
    // 2. while 控制重复的次数
    while (i <= 5) {
        // 3. 打印跑步第几圈
        printf("跑步第 %d 圈\n", i);
        // 4. 条件改变
        i++;
    }

    return 0;
}

do...while语句

text
#include <stdio.h>

int main() {
    // 需求跑步5圈
    // 1. 条件变量的定义
    int i = 1;
    do {
        // 2.1 打印跑步第几圈
        printf("跑步第 %d 圈\n", i);
        // 2.2 条件改变
        i++;
    } while ( i <= 5 ); // 3. 控制重复的次数

    return 0;
}

for语句

text
#include <stdio.h>

int main() {
    // 需求跑步5圈
    for (int i = 1; i <= 5; i++) {
        printf("跑步第 %d 圈\n", i);
    }

    return 0;
}

跳转关键字

break

text
#include <stdio.h>

int main() {
    // 需求: 一共吃5碗饭, 吃到第3碗吃饱了, 结束吃饭动作
    // 1. 定义条件变量,为了查看方便, 计数器从 1 开始
    int i = 1;
    while (i <= 5) { // 2. 控制条件
        if (i == 3) {
            printf("吃饱了,不吃了\n");
            break; // 结束循环,退出循环
        }
        
        printf("吃第 %d 碗饭\n", i);
        // 3. 条件变量改变
        i++;
    }

    return 0;
}

continue

text
#include <stdio.h>

int main() {
    // 需求: 一共吃5个苹果,吃到第3个遇到虫子,这个跳过不吃,下一个继续
    // 1. 定义条件变量,为了查看方便, 计数器从 1 开始
    int i = 1;
    while (i <= 5) { // 2. 控制条件
        if (i == 3) {
            printf("这个有虫子,不吃了\n");
            i++;    // continue 之前一定要修改计数器(条件变量),否则,导致死循环
            continue;; // 跳过本次循环,下次继续
        }
        
        printf("吃第 %d 个苹果\n", i);
        // 3. 条件变量改变
        i++;
    }

    return 0;
}

goto

text
#include <stdio.h>

int main() {

    int i = 0;
    while (i < 3) {
        if(i == 1) {
            goto End;	// 跳转到End标签
        }
        printf("i = %d\n", i);
        i++;
    }
    
    End:
        printf("this is ending!\n");

    return 0;
}

如有转载或 CV 的请标注本站原文地址