转:如何让程序屏蔽CTRL+C和CTRL+Z

一个程序在终端运行时,我们可以CTRL+C退出该程序或者CTRL+Z暂时停止该程序。那么有办法屏蔽这两个操作吗?

首先,得明白CTRL+C和CTRL+Z做了些什么。stty是Linux下的命令,输出和设置命令行控制参数。stty -a能输出所有命令行设置。如下是本博的命令行设置:
$stty -a
speed 38400 baud; rows 48; columns 159; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
可以看到CTRL+C就等于INTR,CTRL+Z就是SUSP,也就是说这两个分别会向程序发送SIGINT和SIGSTOP信号,这两个信号,一个用于终止进程,一个用于暂停进程,即挂起。

信号是Linux系统用于进程间通信的,内核也可以通过它们向程序发送消息。这些信号都很小,Sponge Liu写了篇文章《Linux内核信号处理机制介绍》,深入浅出的走了介绍。

接下来的问题就是,如何屏蔽两个信号。当然,你也可以通过设置stty的方式实现。可以在程序中屏蔽吗?如果可以,如何屏蔽?如果不可以,为啥?

很明显,肯定有些信号不能被屏蔽,比如中断,还应该有杀死进程的信号,要不然内核怎么做操作系统中的老大。实际上,SIGKILL和SIGSTOP信号是不能被屏蔽或阻止的,他们的默认动作总是会被执行的。

那就来个程序,直接屏蔽SIGINT信号吧.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdbool.h>

bool keep_going = true;

void ignore_notice()
{
  keep_going=false;
  printf("recieved SIGINT,and ignore it.\n");
}

void do_something()
{
  int i=0;
  while(i < 1000000)
    {
      i++;
    }
}

int main ()
{
  if(signal(SIGINT, ignore_notice) == SIG_ERR)
  {
    printf("Fail\n");
    return 1;
  }

  while(keep_going)
    do_something();

  printf("program normally exit.\n");
  return 0;
}

下面语句设置针对SIGINT的动作,第二个参数可以传入函数指针,指定处理方式为函数内容,也可以为SIG_IGN,忽略这个信号,或者SIG_DFL,执行默认的动作。
signal(SIGINT, ignore_notice) == SIG_ERR

转自:http://www.lingcc.com/2010/10/12/11305/

C语言中的序列点

此文针对phpchina中的一篇文章而写,可到此围观。
http://bbs.phpchina.com/thread-221621-1-3.html
#include<stdio.h>
main(){
       int i=5,j=5,q,p;
       p = (++i)+(++i)+(++i);
       q = (j++)+(j++)+(j++);
       printf("%d,%d",p,q);
       system("pause");
}
打印出 :22,15
<?php
$i=5;
$m=5;
$b = (++$m)+(++$m)+(++$m);
$d = ($i++)+($i++)+($i++);
echo $b,'--',$d;
输出:21--18
为啥不一样呢?
C的输出感觉不对似的。。。用linux的GCC 和win下面的DEV C++都是 22,15 。。。跟什么有关系吗?

      这个问题其实就是C里面常常被提到的序列点问题,此代码的执行顺序由编译器自行决定。先介绍两个概念。
     副作用:对数据对象或者文件的修改。
    序列点:是一个时间点(在整个表达式全部计算完毕之后或在 ||、 &&、 ? : 或逗号运算符处, 或在函数调用之前), 此刻尘埃落定, 所有的副作用都已确保结束。

阅读剩余部分...

如何查看你可以分配多大内存

#include <stdio.h>
#include <stdlib.h>

int main(void){
    int MB = 0;
    while(malloc(1 << 20))
        ++MB;
    printf("Allocated %d MB total\n", MB);

    return EXIT_SUCCESS;
}

原理,因为2的20次方就是1MB(2的10次方为1KB,2的30次方为1GB,以此类推)。

如果你请求分配的内存块小于1MB,你得到的内存是否比这要多一些呢?为什么?

答:

这不是绝对的!

在本例中使用

1<<22(4MB)得到的结果乘4是2000MB

1<<21(2MB)得到的结果乘2是1972MB

1<<20(1MB)得到的结果是1918MB

1<<19(0.5MB)得到的结果除2是1812MB

1<<18(0.25MB)得到的结果除4是2003MB

1<<17(0.125MB)得到的结果除8是2034MB

显然出现了一个意外的结果。

windows上配置Code::Blocks的wxWidgets以及hello world示例

    很早就安装了Code::Blocks,本来一直想搞VC开发的,今天特意比较了下GTK,QT4,wxsmith这几款windows下的跨平台GUI工具。GTK太老,界面也很丑,安装很麻烦,就没考虑。QT4据说不错,也下了,但没有配置好一个比较合适的开发环境,故还没尝试。由于我安装了Code::Blocks,并且Code::Blocks自带了wxsmith的插件,那就先体验下 wxsminth把。
    首先,下载Code::Blocks 10.05最新的安装包,内置包含mingw的那一个,大约74M。如果要自己配置mingw的话也可以,不过真的很麻烦。GNU的东西要在windows下跑起来很恶心的,咱就还是搞人家编译好的吧。
   下载地址:http://www.codeblocks.org/downloads/26.下载后,安装到任意路径。
    然后,下载wxPack。你也可以下载wxWidgets源代码自行编译,但这真是吃力不讨好,即容易出错,又很耗时。这里我们下载wxPack v2.8.11.03。下载页面:http://wxpack.sourceforge.net/Main/Downloads.它是居于最新的wxWidgets2.8.11编译的。这个安装包有259.9M。但是如果你全部安装的话,有2.5G大小。我们直接安装它,在安装时,会出现一个选择界面,选择安装MSVC和GCC/MINGW版本,若只安装MSVC,要700M空间,若安装GCC/MINGW,则需要2G空间。在这里,为了以后的方便,少些麻烦,我们选择全部安装。反正硬盘不值钱,别舍不得你那点硬盘.假设我们能装在e:/dev/wx目录下(安装目录最好不要带空格和中文)。
     到此为止,基本的环境安装完毕。现在开始开发。
(1)打开code::blocks,选择新建wxWidgets project。

1.png

阅读剩余部分...

转:PHP程序员的C语言学习之路-C语言指针初体现

要了解C语言的指针,首先应该了解内存的结构。下面我先介绍一下内存的结构吧,let’s go

内存就像一个个编好号码的盒子,如下图:
c1.jpg

我们可以任意选择其中的一个盒子存放东西,例如我们要在第一个盒子中放入10个乒乓球,所以我们可以找到编号为1的盒子,然后把10个乒乓球放进里面。

 

计算机的内存跟上面的例子很相似,因为内存也有编号,也可以往里面放东西,所以本质上跟上面的例子没有什么区别的。我们看看内存的真实结构吧:

c2.jpg

在上面的图中,我们看到的图片左边的一些16进制数值就是内存的编号,我们称他为内存地址。而白色框框里面的数据就是保存在内存中的实际数据,我们一般使用的就是这些数据。

好了,已经大概了解过计算机的内存结构了,下面我们来说说什么是指针吧。

定义:指针是一种数据类型,与其它的数据类型不同的是指针是一种用来存放内存的地址的变量。

从上面的定义上可以看出,指针是变量,而且是有类型的变量,但他保存的是内存的地址。这样说来,指针也是很容易理解的。的确,指针就是这么容易。不过要灵活运用指针才能发挥出C语言的最大优势。

 

阅读剩余部分...

PHP程序员的C语言学习之路系列之第二章-C语言里的函数(1)

    C语言的风格是过程式的,按照正常的人类思维,用函数的方式来表达一个处理过程是我们非常习惯的思维方式,因此C语言的运行单位是函数。 (面向对象的思维方式不是正常人的思维习惯,是抽象到一定程度的思维,所以面向对象才那么的难以理解)每一个C语言代码都是以如下基本结构为蓝图的:
//起床函数
void getup()
{
}
//吃饭函数
void eat()
{
}
//睡觉函数
void sleep()
{
}
int main(void)
{
    // 每天重复的生活
    getup();
    eat();
    sleep();
    return 0;
    // 这之后就是我们无法控制的梦乡。。。有可能有一天永远也醒不来了。
   //return后一切over
}
    编写程序也就是按照一定的次序执行不同的功能,最后完成我们的各种目的。这就是C语言里以函数为单元组织编程的思路。那我们先来看看函数的定义和使用。
在C语言里,和php不同的是,变量都需要先声明后使用,函数也是如此。所以你需要先声明一个函数类型,然后才能使用。
先运行下面的代码看看:
#include <stdio.h>
#include <stdlib.h>
int sum;
int add(int x,int y);//声明函数原型
int main()
{
    int arr[]={ 10,20,30 };
    printf("the middle is %d\n",arr<:1:>);
    sum=add(3,5);
     printf("%d",add(7,8));
    return 0;
}
int add(int x,int y)
{
    printf("函数名是:%s\n",__func__);//类似地C也有PHP里类似的魔术常量
    return x+y;
}
   如果add函数在main函数之前定义,那么就不需要声明了。这点和php是不一样的,php的函数可以放在调用之前或之后(当然,也有特例),也不需要实现声明,更不需要返回类型。这点很好理解。
main函数是程序里第一个要执行的函数,其他的函数都可以认为是这个函数的子函数。
函数定义的原型:
类型 名称(参数声明){
函数体
}
类型可以是基本类型,如int变量,也可以是指针,void,还可以包含其他修饰符。
和php一样,C里的函数也可以在另一个文件里声明,然后引入这个文件。如下:
先新建一个test.c文件
#include <stdio.h>
#include "test.h"

int test(char *str)
{
    printf("%s\n", str);
    return 0;
}
通常,为了方便说明一个代码中包含了哪些可以被调用的函数,或者可以被操作的数据,我们需要编写一个头文件作为介面定义,让其他代码可以访问该文件中的函数或者变量,通常取与被描述的代码相同的名字.因此,我们再定义一个test.h文件
#ifndef __TEST_H__          // 如果未定义该宏,则定义出来,防止多次被include
#define __TEST_H__

// 这里开始写对test.c的内容的描述
extern int test(char *str); // 注意结尾必须有分号,extern后重新输入一遍定义

#endif
然后是主文件
#include "test.h"                 // 包含我们对test.c的定义

int main(void)
{
    test("Hello World !");  // 调用我们自己的test函数实现打印
    return 0;
}
是不是和php里的include很像呢,这样就能更好的组织你的代码了.

转:PHP程序员的C语言学习之路系列之第一章, C语言的一些基础

(1)  基本数据类型
     在学习PHP的时候你可能不用知道什么是数据类型, 就算PHP有很多数据类型如: “字符串类型”, “整数类型”, “浮点型类型”等, 但是PHP的数据类型跟C语言的数据类型还是有很大差别的. 为什么这样说? 因为PHP把C语言的数据类型抽象化了. 下面我们想来学习一下C语言的数据类型吧.
    PHP是弱类型语言, 而C语言是强类型语言, 也就是说如果你想使用C语言的变量, 那么你首先要知道变量的类型. 而不像PHP那样变量可以是任何的类型. 另外如果你想使用C语言的变量, 那么你必须先声明这个变量, 然后才可以使用. 如下:

int ivar;
ivar = 10;
如果你没有声明而直接使用变量, 编译会不通过, 如下是错误的:

ivar = 10;
因为PHP不用声明变量就能使用, 所以PHP程序员写C程序时要特别注意声明变量. C语言声明的方式是:
类型 变量名;

如:
int ivar; //定义一个名为ivar的整型变量
char cvar;//定义一个名为cvar的字符型变量
float fvar;//定义一个名为fvar的浮点型变量
double dvar1, dvar2, dvar3;//定义3个双精度类型的变量
long lvar1, lvar2, lvar3;//定义3个长整型的变量

阅读剩余部分...

转:PHP程序员的C语言学习之路系列之入门章编译环境的选择

声明: 首先这个教程是写给有PHP编程基础的童鞋们的, 所以如果你没有PHP编程基础的话, 我还是建议你先学习一下PHP的基础.
入门章, 编译环境的选择
C语言跟PHP不一样, PHP只有装个PHP解析器就可以运行了, 而C还要先编译才可以运行, 一般过程是这样:
c.jpg
C源代码编译之后可以直接在本机运行, 而不必像PHP那样要安装运行环境.
在编译这个过程我们需要一个C语言的编译器. C语言的编译器很多, 著名的有gcc, vc++(IDE)等. 我个人偏向gcc, 因为VC++只能在win平台下使用令人不爽. 不过初学者可以选择安装VC++6.0, 这个版本比较小, 而且容易使用. 我下面介绍一个也挺适合初学者使用的, 就是codeblocks.
先去官网下载一个codeblocks(http://www.codeblocks.org/), 安装完毕后就有编译器和IDE了, 所以挺好用的. 打开codeblocks这样:


好了, 我们试试这个IDE吧.

我们先选择菜单栏的: File -> New -> Empty file, 然后输入以下代码:

#include <stdio.h>
#include <stdlib.h>
int main() {

    printf("Hello World\n");

    return 0;

}
然后保存文件为test.c, 保存后按运行,嗯, 程序运行了, 如下:
helloworld.jpg
这个就是经典的“Hello World”程序了. 以后我们就可以用这个IDE来编写我们的程序了.如果你想使用VC++的话, 可以上网找一下关于VC++的使用的教程, 在这里我就不说了.
因为这章是入门章节, 所以我也不多说了, 下章就开始学习C语言了.

转自:http://blog.sina.com.cn/s/blog_7530db6f0100ppa3.html
    Page :
  1. 1
  2. 2