程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

C语言—基础知识

balukai 2025-05-23 15:22:50 文章精选 4 ℃

编写一个C程序vi HelloWorld.c:创建的c程序文件的后缀一定是.c

#include //添加头文件
int main() //主函数,程序的入口
{
    printf("Hello World!\n");
    return 0;
}

编译C程序:gcc编译器要求源程序的后缀名为.c。
gcc HelloWorld.c:如果程序没有错误,默认会在当前目录下生成一个可执行文件a.out。
gcc HelloWorld.c -o filename:如果程序没有错误,会在当前目录下生成一个通过-o指定文件名的可执行文件。
./a.out:执行编译成功之后的a.out


基本数据类型:数据类型与所占内存空间大小息息相关。


强制转换示例:

#include <stdio.h>
int main()
{
    float f = 1.234;
    printf("%f\n",f);
    printf("%d\n",(int)f); // 强制float类型转换位int类型
    return 0;
}

[root@localhost ~]# gcc model.c
[root@localhost ~]# ./a.out
1.234000
1

概念区分
主存储器:也称为内存储器、内存,是计算机的工作存储器。程序,待处理的数据和处理的结果都存储在内存中。内存通常以字节为单位对存储单元按顺序进行编址。内存读写速度比较快,但只能在加电时存储数据,掉电数据丢失。

外存储器:是用来长期保存数据的大容量存储器,目前多为磁存储器或光存储器。读写速度慢于内存,可以在不加电的情况下长期保存数据。

寄存器:是CPU内部的高速存储器,速度快,数目少。

库函数是封装好的,可以直接拿来用,但是在使用库函数,一定要先包含相应头文件来说明,然后才可以使用。如果想知道某个库函数使用的头文件,我们可以使用man 3 函数名。


程序的设计步骤:编辑(vi)、编译(gcc)、运行调试gdb调试;

GNU的含义:GNU is not Unix。

gcc编译源程序,生成可执行文件分为四步:

  1. 预处理:头文件包含,去注释、宏替换;gcc -E Hello.c -o Hello.i。
  2. 编译:语法或者词法检查,如果没有错误,才会生成汇编文件;否则显示错误信息;gcc -S Hello.i -o Hello.s。
  3. 汇编:生成机器码相关的文件;gcc -c Hello.s -o Hello.o。
  4. 链接,链接函数;ld。
    {}:作用域,用于分清作用域内的数据只在当前作用域生效;

注意:

C标准库 在线速查手册

GCC -l选项:手动添加链接库

GCC调用math.h库时报错的问题分析和解决:
报错现象:在Linux下使用gcc编译c语言时遇到报错:undefined reference to ‘sqrt’。
解决思路:这是因为math.h函数库不在标准库中,使用时需要链接到外部库进行调用。
解决方法:是编译时在命令末尾加上-lm(-l是指定程序链接哪个库,m表示的是数学库)


进制转换

0x12af
= 1 * 16^3 + 2 * 16^2 + 10 * 16^1 + 15 * 16^0
= 4096 + 512 + 160 + 15
= 4783
20 转换二进制: 10100


注释

  1. 多行注释:/* 注释的内容 */
  2. 单行注释 :// 注释内容
  3. 条件注释:#if 0(假) / 1(真) \ 注释内容 #endif
    代码示例:
int demo_annotation(){ //作用域
int x, y; //声明了两个int型变量x,y
// int x; // 单行注释

#if 1 // 条件注释
printf("hello world!\n");
int b = 40;
/* //多行注释
if(b == 40){
b = 99;
int i = 90;
}
*/
#endif
return 0;
}

定位语句:所在文件名、函数名及行号;

int demo_locate_sentence(){
    for (int i = 0; i < 10; i++){
    printf("%s,%s,%d\n", __FILE__, __FUNCTION__, __LINE__); //FILE、FUNCTION、LINE:每个前后都是两个下划线
    // __FILE__:打印语句所在的文件名
    //__FUNCTION__:打印语句所在的函数名
    //__LINE__:打印语句所在的行号
    }
    return 0;
}

逻辑类型:只有两个量true和false,表示逻辑真值和逻辑假值。
代码示例1:

// bool:使用该类型值,就必须加头文件`<stdbool.h>`
#include <stdbool.h>
int demo_bool(){
    bool b = -2;
    if (b){
        printf("It is true!\n");
        printf("%d\n", b);
    }else{
        printf("It is false!\n");
        printf("%d\n", b);
    }
    return 0;
}

代码示例2:

int demo_Bool(){
    // _Bool:使用该类型值,不需要加任何头文件,其值非零既真。
    _Bool b = 2;
    if (b){
        printf("It is true!\n");
        printf("%d\n", b);
    }else{
        printf("It is false!\n");
        printf("%d\n", b);
    }
    return 0;
}

char类型:占有一个字节,一个字节占有8位,默认有符号,决定了char表示的数据范围 ~,最高位是符号位,代表负数,代表正数。

  1. char a = 97=0110 0001
  2. singed char:表示的数据范围是 ~),最高位为符号位;
  3. unsigned char:表示的数据范围是~, 最高位也参与运算;
    代码示例:
int demo_char(){
    /*
    char a = 'a';
    char a = 97; // 上述两种写法都可以
    a = a + 1;
    printf("%c\n", a);
    printf("%d\n", a);
    */
    // char a = 98;
    char a = 128;
    a = 90;
    printf("a= %d\n", a);
    printf("a = %c\n", a);
    unsigned char c2 = -1;
    printf("c2 = %d\n", c2);
    return 0;
}

计算机中数据的存储方式,实际按照数据的补码形式存储。


singed 正数 97

负数 -97

原码

0110 0001

1110 0001

反码

0110 0001

反码 1001 1110 符号位不变,剩余位按位取反

补码

0110 0001

1001 1111 反码


char a = 128;
存储时只看数值,取出是看数据类型

unsigned char c2= -1

原码

1000 0000

1000 0001

反码

1000 0000

1111 1110

补码

1000 0000

1111 1111

原码

1000 0000

1111 1111

反码

1111 1111

1111 1111

补码

1000 0000 取出时:

1111 1111 取出时:

int demo_twos_complement(){
    float f = -3243243243243243212.341234565686; //float默认保留小数点后六位
    printf("%.7f\n", f);
    printf("%e\n", f);
    return 0;
}

-3243243192346214400.0000000
-3.243243e+018

字符常量:指一个单一字符, 其表示形式是由两个单引号包括的一个字符。字符常量的值就是该字符的ASCII码值,实际运算是拿相对应的 ASCII 来参与运算。

int demo_ASCII(){
    char a = 10;
    char b = 20;
    a = 'b';
    char c = 'a' + 1;
    char cc = 'A';
    cc = 'A' + 32;
    printf("c = %d\n", c);
    printf("c = %c\n", c);
    printf("cc = %d\n", cc);
    printf("cc = %c\n", cc);
    return 0;
}

字符串常量:是指用双引号括起来的一串字符来表示的数据。

#include <stdio.h>
int main(){
    char str1[] = "Hello";//字符串常量赋值给字符数组
    char *str2 = "Hello";//字符串常量赋值给字符指针
    /*
    'a' //只包含一个字符常量a
    "a" //除了包含一个字符常量a之外,还有一个字符串结束符‘\0’
    */
    char c1 = 'a';
    char *c2 = "a";//c2 指向字符串的首地址
    int i = 0;
    for(i = 0; i < 2; i++){
        //i = 0 时,取字符串的第一个字符;
        //i = 1 时,取值符串的第二个字符.
        printf("%d\n",*(c2+i));
    }
    return 0;
}

c = 98
c = b
cc = 97
cc = a

字符常量&字符串常量区分:


示例

注意点

字符串常量

char *a = "Hello World!"
char a[] = "Hello World"

默认带\0

字符常量

char a = 'H'

字符常量不带\0


标识符常量:原样替换,可以使用预处理查看替换结果;#define N (8+6)。

#include <stdio.h>
#define N (8+8)
#define M int main(){int a = N * N; printf("a = %d\n",a);return 0;}

题目:个水分子的质量约为克。夸脱水大约是克。编写一个程序,提示用户输入水的夸脱数,并显示水分子数量。(使用scanf函数)

#include <math.h>
int demo_water_number(){
    int quart_number;
    printf("请输入水的总夸脱数:\n");
    scanf("%d", &quart_number);
    printf("%ld\n", (quart_number * 950) / (3.0 * pow(10, -23)));
    return 0;
}

[root@localhost ~]# gcc water_molecule.c
[root@localhost ~]# ./a.out
请输入水的总夸脱数:
166
166夸脱数的水分子数为5.256667e+27

函数

一般形式:

<数据类型> <函数名称>( <形式参数说明> );{
              语句序列;
              return[(<表达式>)];
}

作用:

  1. <函数名称>:是一个标识符,要求符合标识符的命名规则;
  2. <数据类型>:是整个函数的返回值类型,如无返回值应该写为void型;
  3. <形式参数说明>:是逗号”,”分隔的多个变量的说明形式,通常简称为形参;
  4. 大括弧对 {<语句序列> },称为函数体;
  5. <语句序列>是大于等于零个语句构成的。
  6. return[(<表达式>)]语句中表达式的值,要和函数的<数据类型>保持一致;如函数的<数据类型>void可以省略或者无表达式结果返回(即写成return ;)

注意项:

一个完成特定功能的代码模块,其程序代码独立,通常要求有返回值,也可以是空值。

注意:在函数体中,表达式语句里使用的变量必须事先已有说明,否则不能使用。

最近发表
标签列表