Linux C语言开发

No.1 C语言开发基础知识

gcc编译器:

gcc(GNU Compiler Collection)是GNU推出的多平台编译器,可将C、C++源程序编译连接成可执行文件,支持以下后缀:

  1. l.c c语言源代码
  2. l.h  程序所包含的头文件  
  3. l.i  已经预处理过的C源代码文件
  4. l.s  汇编语言源代码文件
  5. l.o  编译后的目标文件

实例解析:

gcc –o hello hello.c

-o  输出可执行文件

-c  只要求编译器输出目标代码(.o文件),而不必输出可执行文件

-g  用于调试

./hello  查看输出结果

gcc做为一个交叉编译器,如何生成ARM平台的执行程序? 

经过gcc编译器最后生成的一大堆机器码只有Linux操作系统认识,但是我们做ARM裸机实验时Soc上是没有linux操作系统的,所以这时候ARM裸机只认识经过ARM指令集生成的机器码。这时候我们要想让可执行文件在ARM裸机上运行就需要使用arm-linux-gcc (交叉编译工具)编译生成的可执行文件。字面理解arm-linu-gcc的意思也就是编写环境是使用Linux主机编写的,然后编译后要在ARM上运行的可执行文件。
附上转载原文出处链接。原文链接:https://blog.csdn.net/yz_cfm/article/details/76998958

数据的表示 :

数值数据的表示(包括二进制、八进制、十进制、十六进制)

基数与各数位的权:

基数是指该进位制中允许选用的基本数码的个数。如十进制数,基数为10, 可选用0、1、2……9共10个不同数码中的任何一个。而位权的大小是以基数为底,数字所在位置的序号为指数的整数次幂。

 基数为2的进位制叫二进制

二进制只有0、1两种数码,计数逢2进位

基数为16的进位制叫十六进制

十六进制有0、1、2…9、a、b、c、d、e、f 共16种数码,计数逢16进位

非数值数据的表示

非数值数据包括文字、符号、图像、语言和逻辑信息等,也都是以0、1形式存在。

字符数据在机器内也被变换成二进制编码的形式。国际上普遍采用的一种编码是美国国家信息交换标准代码,简称为ASCII码。

char       unsigned char      1字节   00000000~11111111  0~255

No.2 数据类型

基本数据类型

逻辑类型。只有两个量true和false,表示逻辑真值和逻辑假值。

整数类型。包括char, short, int和long。

浮点类型。包括float和double。

void类型。主要用于说明不返回值的函数或指向任一类型的指针等。

bool类型

 代码示例:

#include <stdio.h>
#include <stdbool.h>

int main(int argc, char *argv[])
{
        _Bool a;
//        bool a;

        a = true;
        a = false;
        a = -1;
        if (a) {
                printf("true %d\n",a);
        }
        else {
                printf("false %d\n",a);
        }

        return 0;
}

 char类型

 代码示例:

#include <stdio.h>
#include <stdbool.h>

int main(int argc, char *argv[])
{
        unsigned char ch;

        ch = -1; 

        printf("ch=%d %c\n", ch, ch);


        return 0;
}

 整型

 代码示例:

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

int main(int argc, char *argv[])
{

        printf("%d %d %d %d\n", sizeof(_Bool), sizeof(char), sizeof(short), sizeof(int));;

        printf("char:%d-%d\n", SCHAR_MIN, SCHAR_MAX);
        printf("shor:%d-%d\n", SHRT_MIN, SHRT_MAX);
        printf("int:%d-%d\n", INT_MIN, INT_MAX);

        return 0;
}

 浮点型

 代码示例:

#include <stdio.h>

int main(int argc, char *argv[])
{
        float a = 3.14;
        double b = 4.5;

        printf("%f %lf\n", a, b);

        return 0;
}

 强制进行数据类型转换

强制数据类型的转换是指采用某种方式将某种数据类型强制转换成指定的数据类型。包括显式的数据类型转换,和隐式的数据类型转换。

强制类型转换符后面的表达式如存在复杂运算,就一定要用小括号括起来。

强制类型转换符是一种不安全的转换,一般都是将高级类型转换成低级类型,要丢失数据的精度。

强制类型转换并不改变表达式中变量的数据类型和其值。

代码示例:

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

int main(int argc, char *argv[])
{
        int a = 2, b = 3;
        float c = 3.14;
        int sum;

        sum = (int)(a + b + c);
        printf("%d\n", sum);

        return 0;
}

No.3 常量及变量

整型常量:

常量是指在程序运行期间其数值不发生变化的数据。整型常量通常简称为整数。整数可以是十进制数、八进制数和十六进制数。例如,十进制的数值3356可以有下列二种不同的表示形式:八进制数    06434  十六进制数  0xd1c。

浮点常量:

浮点常量又称为实数,一般含有小数部分。在C语言中,实数只有十进制的实数,分为单精度和双精度。实数有两种表示方法, 即一般形式和指数形式。一般实数:3.5,-12.5.指数形式:指数形式的实数一般是由尾数部分、字母e或E和指数部分组成。  当一个实数的符号为正号时,可以省略不写,其表示的一般形式如下:1.176e+10 表示 1.176×1010  -3.5789e-8 表示 -3.5789×10-8 这通常表示特别大或特别小的数。

字符常量:

字符常量是指一个单一字符, 其表示形式是由两个单引号包括的一个字符。例如A’,  ‘a’。字符常量具有数值。字符常量的值就是该字符的ASCII码值。可以把字符常量看做一个字节的正整数。

字符串常量:

所谓字符串常量是指用双引号括起来的一串字符来表示的数据。(字符串以\0结尾) 例如: “9” ==  ‘9’,’\0’ 。

标识常量:

所谓标识常量是指用标识符代替常量使用的一种常量, 其名称通常是一个标识符。标识常量也叫符号常量,一般用大写英文字母的标识符。在使用之前必须预先定义。(注意这里仅仅是进行了替换,但是不会提前对预定义的常量进行运算)

编程实例:

一个水分子的质量约为3.0*10-23g,1夸脱水大约有950g,编写一个程序,要求输入水的夸脱数,然后显示这么多水中包含多少水分子。

#include <stdio.h>

#define W 3.0e-23
#define C 950

int main(int argc, char *argv[])
{
        float n;

        printf("input n:");
        scanf("%f", &n);

        n = n * C / W;
        printf("%f %e\n", n, n);

        return 0;
}

常量思考问题:

1. 用预处理指令 #define 声明一个常数,用以表明一年中有多少秒(忽略闰年问题)

#define SECONDS 60
#define MINUTES 60
#define HOURS 24
#define DAYS 365
#define SECONDS_PER_YEAR DAYS*HOURS*MINUTES*SECONDS  //31536000

2. 以下程序的输出结果是( )
#define M(x,y,z) x*y+z
void main(void){
int a=1, b=2, c=3;
printf("%d\n", M(a+b,b+c,c+a));}
A.19   B.17   C.15   D.12

#define M(x,y,z) x*y+z
void main(void){
int a=1, b=2, c=3;
printf("%d\n", M(a+b,b+c,c+a));
}

//M(a+b,b+c,c+a)) == a + b * b + c + c + a == 1+2*2+3+3+1 == 12

储存变量:

变量在程序中用变量名表示。变量名由用户根据其用途任意命名。变量名由字母、数字、下划线组成,不能以数字开头,不能和C的关键字重名。 在程序运行时,变量占据存储空间的大小由其数据类型决定。变量在内存空间中的首地址,称为变量的地址。

变量说明的一般形式是:<存储类型>    <数据类型 >    <变量名> ; <存储类型>是关键词auto、register、static和extern;<数据类型>可以是基本数据类型,也可以是自定义的数据类型。

AUTO存储类型:

auto说明的变量只能在某个程序范围内使用,通常在函数体内或函数中的复合语句里(默认是随机值)。在函数体的某程序段内说明auto存储类型的变量时可以省略关键字auto。

#include <stdio.h>

int main(int argc, char *argv[])
{
        if (1) {
                int a;

                printf("a=%d\n", a); //输出的值为随机值,证明auto变量不初始化的值是未知的
        }
//        printf("out if:a=%d\n", a);

        return 0;
}

REGISTER存储类型:

register称为寄存器型,register变量是想将变量放入CPU的寄存器中,这样可以加快程序的运行速度。register变量必须是能被CPU所接受的类型。这通常意味着register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。不能用“&”取地址符号来获取register变量的地址。

#include <stdio.h>

int main(int argc, char *argv[])
{
        register int a = 10;

        //printf("out if:a=%d %p\n", a, &a);报错,显示没有地址,证明寄存器变量无法取地址

        return 0;
}

EXTERN存储类型:

当变量在一个文件中的函数体外说明,所有其他文件中的函数或程序段都可引用这个变量。extern称为外部参照引用型,使用extern说明的变量是想引用在其它文件中函数体外部说明的变量。static修饰的变量,其它文件无法使用。

//int global_a = 100;
static int global_a = 100;
//验证static变量声明的变量无法被联合编译并且调用
#include <stdio.h>

extern int global_a;//extern变量,联合编译另一个文件的变量值,并且调用

int main(int argc, char *argv[])
{
        printf("global_a=%d\n", global_a);

        return 0;
}

STATIC存储类型:

static变量称为静态存储类型的变量,既可以在函数体内,也可在函数体外说明。(默认是0)局部变量使用static修饰,有以下特点:在内存中以固定地址存放的,而不是以堆栈方式存放。只要程序没结束,就不会随着说明它的程序段的结束而消失,它下次再调用该函数,该存储类型的变量不再重新说明,而且还保留上次调用存入的数值。

#include <stdio.h>

int main(int argc, char *argv[])
{
        int i = 1;

        while (i < 5) {
//             int a;
                static int a;
                a++;
                printf("a=%d\n", a);//和auto变量进行对比,验证了static变量在声明时默认值为0
                i++;
        }
        return 0;
}

问题:修饰局部变量时,auto和static和register有什么区别?

  • auto关键字是默认的存储类别说明符,用于定义自动变量。
  • static关键字用于定义静态变量,具有静态存储期。
  • register关键字用于提示编译器将变量存储在寄存器中,但实际是否存储在寄存器中取决于编译器的优化策略。

变量思考问题:

1. 简述使用static关键字修饰一个局部变量时与不使用该关键字声明一个局部变量有什么异同。

当使用static关键字修饰一个局部变量时,只要程序还没结束,那么该变量就不会随着说明它的程序段的结束而消失,它下次再调用该函数,该变量不再重新说明,而且还保留上次调用存入的数值。我的理解为该关键字会声明一个静态变量,程序不结束,该变量的数值为上次调用存入的数值。同时如果不给其赋值,则默认为赋值0。
2. 使用extern关键字声明的变量代表什么?

当使用extern关键字在一个文件中的函数体外说明一个变量,那么,所有其他文件中的函数或程序段都可引用这个变量。当使用其他文件引用该变量时,需要同时编译两个文件。(和static的区别,static修饰的全局变量,其它文件无法使用)

No.4 运算符

算术运算符:

#include <stdio.h>

int main(int argc, char *argv[])
{
        float a = 15, b = 8, c;

        c = a + b;
        printf("c=%f\n", c);
        c = a * b;
        printf("c=%f\n", c);
        c = a / b;
        printf("c=%f\n", c);
        //c = a % b;
        //printf("c=%f\n", c);  两个float无法取余

        return 0;
}


int main(int argc, char *argv[])
{
        int x = 15, y = 5, z;

#if 0
        y = ++x;
        printf("x=%d y=%d\n", x, y);

        y = x++;
        printf("x=%d y=%d\n", x, y);
#endif

        z = ++x + y++;
        printf("x=%d y=%d z=%d\n", x, y, z);

        return 0;
}

关系运算符:

逻辑运算符:

 

#include <stdio.h>

int main(int argc, char *argv[])
{
        int x = 5, y = 4, z;

        if (x != 5 || y++) { // true z = x + y = 5 + 5 = 10
        //if (x != 6 && y++) {
                z = x + y;
                printf("true:x=%d, y=%d,z=%d\n", x, y, z);
        }
        else {
                z = x - y;
                printf("false:x=%d, y=%d,z=%d\n", x, y, z);
        }

        return 0;
}

位运算符:

逻辑取反:

逻辑或:

逻辑与:

异或运算:

移位运算: 

复合运算符:

三目运算符:

#include <stdio.h>

int main(int argc, char *argv[])
{
        int x = 70, y = 10;

        //y = x++ > 70 ? x + y : 5; // x = 71 ,5
        y = ++x > 70 ? x + y : 5; // x =71, x + y = 81

        printf("x=%d y = %d\n", x, y);

        return 0;
}

特殊运算符:

逗号运算符以及sizeof运算符

#include <stdio.h>

int main(int argc, char *argv[])
{
        int a = 5;
        long b = 3;
        long long c = 9;

        printf("%d %d %d\n", sizeof(a), sizeof(b), sizeof(c));
        printf("%d %d %d\n", sizeof(int), sizeof(long), sizeof(long long));

        return 0;
}

 逗号运算符:

#include <stdio.h>

int main(int argc, char *argv[])
{
        int x = 1, y = 0, z = 0, a;

        a = (x += y == z, y = x + 2, z = x + y + x > 0);

        printf("x=%d y = %d z=%d a=%d\n", x, y, z, a);
	//逗号运算符,从左至右运行,将最后一个运算式的值赋给变量
        return 0;
}

运算符优先级:

 注意:逗号运算符的优先级是最低的,而且单个等号=的优先级是低于双等号==

#include <stdio.h>

int main(int argc, char *argv[])
{
        int x = 1, y = 0, z = 0;

//        if (x++ && y++ || ++z)
        if (!(x+1)>0 && y++ || ++z)
                printf("true:%d %d %d\n", x, y, z);
        else 
                printf("false:%d %d %d\n", x, y, z);

        return 0;
}

思考问题:

如何把一个无符号数的某位快速置1?

如果想将某个无符号的数的某一位至1的话,那么只需要将这个数和将1左移这个位数减一位的值进行或运算即可,那么假设这个数为X,需要将X的Y位至1,则有X = X | (1 << (Y - 1))

如何把一个无符号数的某位快速清0?

如果将某一位进行至0,则有X = X & (~(1 << (Y - 1))),如果想要将一个10进制的数进行改为16进制,X/16的操作可以理解为这个数右移4位,(一个数左移一位等于乘2,右移等于除2),X%16可以理解位这个数和0xf进行&运行就好。

实践问题:

1. 浮点数可以参与除法运算么?那么取余运算呢?
2. 在位运算中,某操作数右移3位,其结果相当于?
A.操作数除以6    B.操作数乘以6   C.操作数除以8  D.操作数乘以8

1.浮点数可以参与除法运算,但是取余运算只能用于整数之间的运算,不能用于浮点数。
2.C

有以下程序    unsigned int a = 0x20;    a = a >> 2;   a = ~a;   执行完该程序后变量a的值是多少?

0xfffffff7

No.5 输入输出

No.6 控制语句

No.7 循环语句

No.8 数组

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Linux下编写C语言程序,需要先安装C编译器,比如gcc。然后可以使用任何文本编辑器编写C代码,比如vi、nano、gedit等。编写完代码后,使用gcc命令进行编译,生成可执行文件。最后使用./可执行文件名命令运行程序。 ### 回答2: 在Linux下编写C语言程序是一件非常常见的事情。Linux作为一个开放源代码的操作系统,其内核就是用C语言编写的,因此Linux非常支持C语言开发开发环境的搭建 在Linux开发C语言程序,需要一个能够编写、编辑和编译C语言开发环境。Linux常用的C语言开发环境包括:Vim、Emacs、GCC等等。其中,Vim和Emacs是比较常见的代码编辑器,可以用于编写代码和调试程序;GCC是一款非常强大的编译器,可以将C语言代码转化为可执行文件。在Linux中,通常是使用命令行来进行这些操作,比如输入“gcc -o hello hello.c”就可以把hello.c这个源代码编译成一个可执行文件hello。 编写代码 在Linux下,可以使用Vim或Emacs等文本编辑器来编写C语言代码。对于使用Vim来编写代码的用户,可以在终端里输入“vim hello.c”来创建一个空的hello.c文件,并开始编辑代码。对于使用Emacs的用户,可以在终端里输入“emacs hello.c”来打开Emacs编辑器,并开始编写代码。 编写代码的过程,包括C语言的语法、函数库的使用、变量的定义等等。对于初学者来说,可以先学习基础语法,逐步掌握其它知识点。在编写代码的过程中,建议注重代码的可读性和可维护性,遵循良好的编程规范。 编译代码 在编写好C语言代码之后,需要将其编译成可执行文件。在Linux下,通常使用gcc工具来进行编译。在终端里输入“gcc -o hello hello.c”命令,可以编译将hello.c文件编译成可执行文件hello。 运行程序 在编译完成之后,就可以运行程序了。在终端里输入“./hello”命令,就可以执行可执行文件hello。程序运行时,可以观察程序的输出和执行结果,以改善程序的性能和逻辑。 总结 在Linux下编写C语言程序,需要一个能够编辑和编译代码的开发环境,了解C语言的语法、函数库的使用、变量的定义、编码规范等知识。在编写代码时,注重代码的可读性和可维护性,尽量减少程序出现问题的可能性。编译代码完成之后,可以运行程序,观察其运行结果以改进代码的逻辑和性能。 ### 回答3: 在Linux操作系统下编写C语言程序是一项基本技能,因为Linux是一个开源的操作系统,C语言也是开源且运用广泛的编程语言。下面会介绍一些有关在Linux下编写C语言程序的基本知识。 首先,要编写C程序,我们需要安装一个文本编辑器,比如说vim、emacs、gedit等,它们都是Linux下常用的文本编辑器,可以实现代码高亮和自动缩进等功能。我们可以使用命令行方式打开编辑器,比如说: ``` vi test.c ``` 其中,test.c是文件名,vi是文本编辑器的命令。可以在编辑器中输入C语言代码,如下: ```c #include<stdio.h> int main() { printf("Hello World!"); return 0; } ``` 保存并退出编辑器:按“:wq”(即依次按冒号、w、q键)。 执行C程序时,通过gcc或clang工具进行编译。比如说: ``` gcc test.c -o test ./test ``` 其中,gcc是编译器名字,test.c是源文件名,-o选项后面跟着要生成的程序名,./test在终端中输入可以执行生成的程序。需要注意的是,要确保系统中已经安装好了gcc或clang等工具。 在写程序的时候,还要注意一些比较重要的细节: 1. 在源文件中加入正确的头文件,比如说stdio.h、stdlib.h、string.h等,这些头文件定义了常用函数、变量和宏等,可以方便我们编写代码。 2. 代码排版要规范,加入适当的注释和空格等,可以提高代码的可读性。 3. 对于程序逻辑错误、内存泄露等问题,可以通过调试工具进行排查,比如说gdb。可以通过gdb命令行调试或者在代码中用printf输出调试信息。 总之,在Linux下编写C语言程序和在其他操作系统下编写并没有太大的区别,需要重点关注的是编译器、编辑器、头文件等环境问题。同时,要加强自身对C语言的学习和理解,这样才能编写更加高效、优雅、稳定的程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值