C issue2
堆栈空间C源代码进过预处理、编译、汇编和链接4步生成一个可执行程序。程序在没有运行之前,也就是说程序没有被加载到内存前,可执行程序内部已经分好3段信息,分别是代码区(text)、数据区(data)和未初始化数据区(bss)三个部分。(部分人直接把data和bss合起来叫做全局区或静态区)。运行可执行程序,系统把程序加载到内存,除了根据可执行程序的信息分出代码区、初始化数据区和未初始化数据区之外,还额外增加了栈区和堆区。
linux下的内存分配:
结构体和结构体指针的内存申请12345678910111213141516171819202122232425262728293031323334#include<stdio.h>#include<stdlib.h>//包含malloc函数的头文件#include<string.h>typedef struct student//typedef可以将struct student结构体类型用std替代{ char name[20]; int number; char subjec ...
进程
进程argc 和 argv 传参是如何实现的呢?
当在终端执行程序时,命令行参数(command-line argument)由 shell 进程逐一进行解析,shell 进程会将这些参数传递给加载器,加载器加载应用程序时会将其传递给应用程序引导代码,当引导程序调用 main()函数时,在由它最终传递给 main()函数,如此一来,在我们的应用程序当中便可以获取到命令行参数了。
注册进程终止处理函数atexit()
12#include <stdlib.h>int atexit(void (*function)(void));
function:函数指针,指向注册的函数,此函数无需传入参数、无返回值。返回值:成功返回 0;失败返回非 0。
进程是操作系统对一个正在运行的程序的一种抽象。
进程是一个动态过程,而非静态文件,它是程序的一次运行过程,当应用程序被加载到内存中运行之后它就称为了一个进程,当程序运行结束后也就意味着进程终止,这就是进程的一个生命周期。*
在应用程序中,可通过系统调用 getpid()来获取本进程的进程号
1234#include <sys/ty ...
C错题
11234567#include <stdio.h>int main() { int i = 1; sizeof(i++); printf("%d\n", i); return 0;}
输出等于1
根据C99规范, sizeof是一个编译时刻就起效果的运算符,在其内的任何运算都没有意义,sizeof(i++); 在编译的时候被翻译成 sizeof((i++的数据类型)) 也就是 sizeof(int); 不会执行i++了 。
sizeof是操作符
2下面说法中正确的是()
若全局变量仅在单个C 文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度
123- ``` 若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度
```设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑变量生命周期问题
123- ``` 静态全局变量使用过多,可那会导致动态存储区(堆栈)溢出
Static 函数在非类中有三个作 ...
信号
信号是事件发生时对进程的通知机制,也可以把它称为软件中断。信号与硬件中断的相似之处在于能够打断程序当前执行的正常流程,其实是在软件层次上对中断机制的一种模拟。大多数情况下,是无法预测信号达到的准确时间,所以,信号提供了一种处理异步事件的方法。
产生信号的方式:
⚫ 硬件发生异常,即硬件检测到错误条件并通知内核,随即再由内核发送相应的信号给相关进程。硬件检测到异常的例子包括执行一条异常的机器语言指令,诸如,除数为 0、数组访问越界导致引用了无法访问的内存区域等,这些异常情况都会被硬件检测到,并通知内核、然后内核为该异常情况发生时正在运行的进程发送适当的信号以通知进程。⚫ 用于在终端下输入了能够产生信号的特殊字符。譬如在终端上按下 CTRL + C 组合按键可以产生中断信号(SIGINT),通过这个方法可以终止在前台运行的进程;按下 CTRL + Z 组合按键可以产生暂停信(SIGCONT),通过这个方法可以暂停当前前台运行的进程。⚫ 进程调用 kill()系统调用可将任意信号发送给另一个进程或进程组。当然对此是有所限制的,接收信号的进程和发送信号的进程的所有者必须相同,亦或者发送信号的进 ...
Linux系统信息与系统资源
系统信息与系统资源系统信息系统标识uname系统调用uname()用于获取有关当前操作系统内核的名称和信息,原型可以通过man 2 uname查看
函数参数和返回值含义如下:buf:struct utsname 结构体类型指针,指向一个 struct utsname 结构体类型对象。返回值:成功返回 0;失败将返回-1,并设置 errno。
uname()函数用法非常简单,先定义一个 struct utsname 结构体变量,调用 uname()函数时传入变量的地址即可,struct utsname 结构体如下所示:
12345678910struct utsname { char sysname[]; /* 当前操作系统的名称 */ char nodename[]; /* 网络上的名称(主机名) */ char release[]; /* 操作系统内核版本 */ char version[]; /* 操作系统发行版本 */ char machine[]; /* 硬件架构类型 */ #ifdef _GNU_SOURCE char domainname[];/* 当前域名 */ ...
Linux调试工具gdb
linux中使用C/C++的调试工具gdbgdb是GNU开源组织发布的一个强大的Linux下的程序调试工具。
一般来说,GDB主要帮助你完成下面四个方面的功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。首先要用gcc进行编译
1gcc -g 源文件 -o 目标文件
gdb的命令
(gdb)help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h
(gdb)run:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r
(gdb)start:单步执行,运行程序,停在第一执行语句
(gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l
(gdb)set:设置变量的值
(gdb)next:单步调试(逐过程,函数直接执行),简写n
(gdb)ste ...
学习一个阶段的感受
因为疫情原因提前放假回家,大部分考试还不知道怎么考,现在要准备好材料,刷网课和弄选修论文,打算12月份学完C语言剩余两章,之后每天写个联系代码,linux方面继续应用层的编写学习,看看弄完后,可能要进入到C++,这样才能学习QT应用编程,东西还是不少的,先完成总的百分之40吧。
待续。。。
现在进入假期了,为了更好的使用linux的开发板,开始学习裸机开发,uboot和系统移植,驱动开发相关知识。
看看之后学习C++,进入qt来更好的制作一个完整的项目。
C issue1
scanf输入问题-输入缓冲区1234567891011121314151617181920212223int main(void){ char ch; int i=0; int b; b=scanf("%c",&ch); while(b == 1) { printf("%d",i++); printf("?"); b=scanf("%c",&ch);\ } printf("Done\n"); return 0;}//会得到```ca//输入a0?a1?
原因是因为scanf()函数会把回车、空格、Tab或一些不合理输入的字符当作此次输入的结束标志,它不会把这些字符输入到想要保存此次输入数据的变量中,而是把这些字符遗留在了输入缓冲区,那么,当下一次想要从标准输入中读取一个字符时,这个遗留的字符就正好充当了此次的输入字符。
程序在输入a后输入了回车来结束此次输入,那么回车就遗留在了输入缓冲区,当需要给c输入字符时,它自动的充 ...
Linux——字符串处理
字符串处理字符串输入输出设备输出stdout、设备键盘输入stdin、设备错误显示stderr。
常用的字符串输入函数有putchar()、puts()、fputc()、fputs()只能输出字符串函数,不像printf可以格式化输出,所以一般用printf。
puts函数原型可通过man 3 puts查看。
使用 puts()函数连换行符’ \n ‘都省了,函数内部会自动在其后添加一个换行符。
putchar函数原型可通过man 3 putchar查看。
putchar()函数可以把参数 c 指定的字符(一个无符号字符)输出到标准输出设备,其输出可以是一个字符,可以是介于 0~127 之间的一个十进制整型数(包含 0 和 127,输出其对应的 ASCII 码字符),也可以是用 char 类型定义好的一个字符型变量。
fputc函数原型可通过man 3 fputc查看
fputc()与 putchar()类似,也用于输出参数 c 指定的字符(一个无符号字符),与 putchar()区别在于,putchar()只能输出到标准输出设备,而 fputc()可把字符输出到指定的文件中,既可以是 ...
学习一个阶段的感受
目前在linux上学习了一个浅显的阶段,学会了命令行的一些常规的操作,也对Linux的内核有了少部分的了解,目前在C语言上的系统学习进入了尾声,之后应该就要时常复习C语言的编程,之前没有编写过底层,现在感觉C语言的应用编写确实复杂,主要是东西有点多,记不下来,打算趁着写选修论文的时候,用平时笔记复习复习,再加强一下C语言前些章节的编写能力,跨过这一阶段,再思考下一阶段科技树点哪的问题吧,科技树可真多呀,只能说还好现在课业不是很重。

