C指针原理(46)-C应用技巧(1)
字符串小寫轉(zhuǎn)大寫
#include
int main(void)
{
int i=0;
char string[100];
strcpy(string,“abcdefghijklmnopqrstuvwxyz”);
while (string[i]!=’\0’){ //將小寫轉(zhuǎn)化成大寫
if (islower(string[i]))
string[i]=toupper(string[i]);
}
printf("%s\n",string);
return 0;
}
linux-C獲得用戶信息和節(jié)點信息
C代碼
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <pwd.h>
int main(void){//
char hname[256];//節(jié)點名稱
struct utsname uts;//節(jié)點結(jié)構(gòu)信
uid_t uid;
gid_t gid;
struct passwd *pw;
printf(“主機名:%s\n”,hname);
printf(“系統(tǒng)名稱:%s\n 機器名稱:%s\n”,uts.sysname,uts.machine);
printf(“節(jié)點名稱:%s\n”,uts.nodename);
printf(“版本:%s,版本號%s”,uts.release,uts.version);//系統(tǒng)版本,版本號
//取得當(dāng)前用戶登陸情況
uid=getuid();
gid=getgid();
pw=getpwuid(uid);
printf(“用戶id 為%d,用戶組為%d\n”,uid,gid);
printf(“用戶真實姓名%s\n用戶名稱:%s\n”,pw->pw_gecos,pw->pw_name);
printf(“用戶uid:%s\ngid:%s\n”,pw->pw_uid,pw->pw_gid);
printf(“主目錄:%s\n”,pw->pw_dir);
printf(“用戶shell:%s\n”,pw->pw_shell);
}
運行:
gcc -o test7 test7.c
test7.c: In function ‘main’:
test7.c:13: warning: incompatible implicit declaration of built-in function ‘printf’
test7.c:14: warning: incompatible implicit declaration of built-in function ‘exit’
test7.c:17: warning: incompatible implicit declaration of built-in function ‘printf’
./test7
主機名:puppypc
系統(tǒng)名稱:Linux
機器名稱:i686
節(jié)點名稱:puppypc
版本:2.6.30.5,版本號#1 SMP Tue Sep 1 15:48:26 GMT-8 2009用戶id 為0,用戶組為0
用戶真實姓名root
用戶名稱:root
用戶uid:(null)
gid:(null)
主目錄:/root
用戶shell:/bin/sh
用戶密碼:x
linux-C產(chǎn)生臨時文件
#include <stdio.h>
int main(void){
char tmpname[L_tmpnam];
char *filename;
FILE *fp;
strcpy(tmpname,"/tmp/dfXXXXXX");//file name:df…
filename=mktemp(tmpname);//generate tempfile
printf(“temporary file name:%s\n”,filename);
fp=tmpfile();
if (fp) printf(“temporary file oepn.\n”);
else perror(“error”);
exit(0);
}
linux-文件屬性及目錄基本操作
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <dirent.h>
int main(int argc,char *argv[]){
int i;
struct stat buf;
char *ptr;
if (argc<2){
printf(“filename error”);
exit(1);
}
if (lstat(argv[1],&buf)<0){//lstat和stat 判斷文件屬性,但lstat只判斷連接文件本身,不追蹤真實文件
perror(“l(fā)stat error”);
}
if (S_ISREG(buf.st_mode)) ptr=“普通文件”;
else if(S_ISDIR(buf.st_mode)) ptr=“目錄”;
else if(S_ISCHR(buf.st_mode)) ptr=“字符設(shè)備”;
else if(S_ISFIFO(buf.st_mode)) ptr=“有名管道”;
else if(S_ISLNK(buf.st_mode)) ptr=“符號鏈接”;
else if(S_ISBLK(buf.st_mode)) ptr=“塊設(shè)備”;
else if(S_ISSOCK(buf.st_mode)) ptr=“SOCKET”;
else ptr=“未知設(shè)備”;
printf(“FILE %s is %s file”,argv[1],ptr);
if (S_ISREG(buf.st_mode)){//如果是文件名
printf(“file size is %d bytes.\n”,buf.st_size);
}
if (S_ISDIR(buf.st_mode)){//如果是目錄名,則ls目錄的文件
DIR *dp;
struct dirent *dirp;
if ((dp=opendir(argv[1]))==NULL) perror(“opendir error”);
while ((dirp=readdir(dp))!=NULL){
printf("%s\n",dirp->d_name); //輸出目錄下的文件名
}
closedir(dp);
free(dirp);
}
return 0;
}
c-文件操作-文件位置
CC++C#FP
long file_pos=ftell(fp);//返回當(dāng)前文件位置
fgetpos(fp,&fp_pos);//返回當(dāng)前文件位置到fp_pos中
fsetpos(fp,&fp_pos);//設(shè)置當(dāng)前文件位置為fp_pos
rewind(fp);//把文件置在起始處
linux-多線程-互斥鎖在多進程共享
C代碼
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){//2個進程,一個進程完成每次加1,另一個進程完成每次加2,2個進程協(xié)作完成累加,使用共享內(nèi)存方式在進程間通信
int *x;
int rt;
int shm_id;
char *addnum=“myadd”;
char *ptr;
pthread_mutex_t mutex;//互斥對象
pthread_mutexattr_t mutexattr;//互斥對象屬性
pthread_mutexattr_init(&mutexattr);//初始化互斥對象屬性
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED);//設(shè)置互斥對象為PTHREAD_PROCESS_SHARED共享,即可以在多個進程的線程訪問,PTHREAD_PROCESS_PRIVATE為同一進程的線程共享
rt=fork();//復(fù)制父進程,并創(chuàng)建子進程
//deepfuture.iteye.com,深未來技術(shù)原創(chuàng)
if (rt==0){//子進程完成x+1
shm_id=shm_open(addnum,O_RDWR,0);
ptr=mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,0);/連接共享內(nèi)存區(qū)/
x=(int *)ptr;
}
else{//父進程完成x+2
shm_id=shm_open(addnum,O_RDWR|O_CREAT,0644);
ftruncate(shm_id,sizeof(int));
ptr=mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,0);/連接共享內(nèi)存區(qū)/
x=(int *)ptr;
}
shm_unlink(addnum);//刪除共享名稱
munmap(ptr,sizeof(int));//刪除共享內(nèi)存
return(0);
}
編譯
deepfuture@deepfuture-laptop:~/private/mytest$ gcc -lpthread -std=c99 -lrt -o testmutex testmutex.c
執(zhí)行
deepfuture@deepfuture-laptop:~/private/mytest$ ./testmutex
x+=2:2
x++:3
x+=2:5
x++:6
x+=2:8
x++:9
x+=2:11
x++:12
x+=2:14
x++:15
x+=2:17
x++:18
x+=2:20
x++:21
x+=2:23
x++:24
x+=2:26
x++:27
x+=2:29
x++:30
一、什么是共享內(nèi)存區(qū)
共享內(nèi)存區(qū)是最快的可用IPC形式。它允許多個不相關(guān)的進程去訪問同一部分邏輯內(nèi)存。如果需要在兩個運行中的進程之間傳輸數(shù)據(jù),共享內(nèi)存將是一種效率極高的解決方案。一旦這樣的內(nèi)存區(qū)映射到共享它的進程的地址空間,這些進程間數(shù)據(jù)的傳輸就不再涉及內(nèi)核。這樣就可以減少系統(tǒng)調(diào)用時間,提高程序效率。
共享內(nèi)存是由IPC為一個進程創(chuàng)建的一個特殊的地址范圍,它將出現(xiàn)在進程的地址空間中。其他進程可以把同一段共享內(nèi)存段“連接到”它們自己的地址空間里去。所有進程都可以訪問共享內(nèi)存中的地址。如果一個進程向這段共享內(nèi)存寫了數(shù)據(jù),所做的改動會立刻被有訪問同一段共享內(nèi)存的其他進程看到。
要注意的是共享內(nèi)存本身沒有提供任何同步功能。也就是說,在第一個進程結(jié)束對共享內(nèi)存的寫操作之前,并沒有什么自動功能能夠預(yù)防第二個進程開始對它進行讀操作。共享內(nèi)存的訪問同步問題必須由程序員負責(zé)。可選的同步方式有互斥鎖、條件變量、讀寫鎖、紀錄鎖、信號燈。
二、mmap
在講共享內(nèi)存前我們要先來介紹下面幾個函數(shù)。
mmap函數(shù)把一個文件或一個Posix共享內(nèi)存區(qū)對象映射到調(diào)用進程的地址空間。使用該函數(shù)有三個目的:
1.使用普通文件以提供內(nèi)存映射I/O
2.使用特殊文件以提供匿名內(nèi)存映射。
3.使用shm_open以提供無親緣關(guān)系進程間的Posix共享內(nèi)存區(qū)。
函數(shù)1.
名稱:: mmap
功能: 把I/O文件映射到一個存儲區(qū)域中
頭文件: #include <sys/mman.h>
函數(shù)原形:
void mmap(void addr,size_t len,int prot,int flag,int filedes,off_t off);
參數(shù):
addr 指向映射存儲區(qū)的起始地址
len 映射的字節(jié)
prot 對映射存儲區(qū)的保護要求
flag flag標志位
filedes 要被映射文件的描述符
off 要映射字節(jié)在文件中的起始偏移量
返回值:
若成功則返回映射區(qū)的起始地址,若出錯則返回MAP_FAILED
addr參數(shù)用于指定映射存儲區(qū)的起始地址。通常將其設(shè)置為NULL,這表示由系統(tǒng)選擇該映射區(qū)的起始地址。
filedes指要被映射文件的描述符。在映射該文件到一個地址空間之前,先要打開該文件。len是映射的字節(jié)數(shù)。
off是要映射字節(jié)在文件中的起始偏移量。通常將其設(shè)置為0。
prot參數(shù)說明對映射存儲區(qū)的保護要求。可將prot參數(shù)指定為PROT_NONE,或者是PROT_READ(映射區(qū)可讀),PROT_WRITE(映射區(qū)可寫),PROT_EXEC(映射區(qū)可執(zhí)行)任意組合的按位或,也可以是PROT_NONE(映射區(qū)不可訪問)。對指定映射存儲區(qū)的保護要求不能超過文件open模式訪問權(quán)限。
flag參數(shù)影響映射區(qū)的多種屬性:
MAP_FIXED 返回值必須等于addr.因為這不利于可移植性,所以不鼓勵使用此標志。
MAP_SHARED 這一標志說明了本進程對映射區(qū)所進行的存儲操作的配置。此標志指定存儲操作修改映射文件。
MAP_PRIVATE 本標志導(dǎo)致對映射區(qū)建立一個該映射文件的一個私有副本。所有后來對該映射區(qū)的引用都是引用該副本,而不是原始文件。
要注意的是必須指定MAP_FIXED或MAP_PRIVATE標志其中的一個,指定前者是對存儲映射文件本身的一個操作,而后者是對其副本進行操作。
mmap成功返回后,fd參數(shù)可以關(guān)閉。該操作對于由mmap建立的映射關(guān)系沒有影響。為從某個進程的地址空間刪除一個映射關(guān)系,我們調(diào)用munmap.
函數(shù)2.
名稱:: munmap
功能: 解除存儲映射
頭文件: #include <sys/mman.h>
函數(shù)原形: int munmap(caddr_t addr,size_t len);
參數(shù):
addr 指向映射存儲區(qū)的起始地址
len 映射的字節(jié)
返回值: 若成功則返回0,若出錯則返回-1
其中addr參數(shù)是由mmap返回的地址,len是映射區(qū)的大小。再次訪問這些地址導(dǎo)致向調(diào)用進程產(chǎn)生一個SIGSEGV信號。
如果被映射區(qū)是使用MAP_PRIVATE標志映射的,那么調(diào)用進程對它所作的變動都被丟棄掉。
內(nèi)核的虛存算法保持內(nèi)存映射文件(一般在硬盤上)與內(nèi)存映射區(qū)(在內(nèi)存中)的同步(前提它是MAP_SHARED內(nèi)存區(qū))。這就是說,如果我們修改了內(nèi)存映射到某個文件的內(nèi)存區(qū)中某個位置的內(nèi)容,那么內(nèi)核將在稍后某個時刻相應(yīng)地更新文件。然而有時候我們希望確信硬盤上的文件內(nèi)容與內(nèi)存映射區(qū)中的文件內(nèi)容一致,于是調(diào)用msync來執(zhí)行這種同步。
函數(shù)3.
名稱:: msync
功能: 同步文件到存儲器
頭文件: #include <sys/mman.h>
函數(shù)原形: int msync(void addr,size_t len,int flags);
參數(shù):
addr 指向映射存儲區(qū)的起始地址
len 映射的字節(jié)
prot flags
返回值: 若成功則返回0,若出錯則返回-1
其中addr和len參數(shù)通常指代內(nèi)存中的整個內(nèi)存映射區(qū),不過也可以指定該內(nèi)存區(qū)的一個子集。flags參數(shù)為MS_ASYNC(執(zhí)行異步寫),MS_SYNC(執(zhí)行同步寫),MS_INVALIDATE(使高速緩存的數(shù)據(jù)實效)。其中MS_ASYNC和MS_SYNC這兩個常值中必須指定一個,但不能都指定。它們的差別是,一旦寫操作已由內(nèi)核排入隊列,MS_ASYNC即返回,而MS_SYNC則要等到寫操作完成后才返回。如果還指定了MS_INVALIDATE,那么與其最終拷貝不一致的文件數(shù)據(jù)的所有內(nèi)存中拷貝都失效。后續(xù)的引用將從文件取得數(shù)據(jù)。
函數(shù)4.
名稱:: memcpy
功能: 復(fù)制映射存儲區(qū)
頭文件: #include <string.h>
函數(shù)原形: void memcpy(void dest,const void src,size_t n);
參數(shù):
dest 待復(fù)制的映射存儲區(qū)
src 復(fù)制后的映射存儲區(qū)
n 待復(fù)制的映射存儲區(qū)的大小
返回值:
返回dest的首地址
memcpy拷貝n個字節(jié)從dest到src。
下面就是利用mmap函數(shù)影射I/O實現(xiàn)的cp命令。
/mycp.c/
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc,char *argv[])
{
int fdin,fdout;
void *arc,dst;
struct stat statbuf;
if(argc!=3)
{
printf(“please input two file!\n”);
exit(1);
}
if((fdin=open(argv[1],O_RDONLY))<0) /打開原文件/
perror(argv[1]);
if((fdout=open(argv[2],O_RDWR|O_CREAT|O_TRUNC))<0)/創(chuàng)建并打開目標文件/
perror(argv[2]);
if(fstat(fdin,&statbuf)<0) /獲得文件大小信息/
printf(“fstat error”);
if(lseek(fdout,statbuf.st_size-1,SEEK_SET)==-1)/初始化輸出映射存儲區(qū)/
printf(“l(fā)seek error”);
if(write(fdout,”1”)!=1)
printf(“write error”);
if((src=mmap(0,statbuf.st_size,PROT_READ,MAP_SHARED,fdin,0))==MAP_FAILED)
/映射原文件到輸入的映射存儲區(qū)/
printf(“mmap error);
if((dst=mmap(0,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fdout,0)) ==MAP_FAILED) /映射目標文件到輸出的映射存儲區(qū)/
printf(“mmap error);
memcpy(dst,src,statbuf.st_size);/復(fù)制映射存儲區(qū)/
munmap(src,statbuf.st_size); /解除輸入映射/
munmap(dst,statbuf.st_size); /解除輸出映射/
close(fdin);``
close(fdout);
}
下面是運行結(jié)果:
#cc –o mycp mycp.c
#./mycp test1 test2
三、posix共享內(nèi)存函數(shù)
posix共享內(nèi)存區(qū)涉及兩個步驟:
1、指定一個名字參數(shù)調(diào)用shm_open,以創(chuàng)建一個新的共享內(nèi)存區(qū)對象或打開一個已存在的共享內(nèi)存區(qū)對象。
2、調(diào)用mmap把這個共享內(nèi)存區(qū)映射到調(diào)用進程的地址空間。傳遞給shm_open的名字參數(shù)隨后由希望共享該內(nèi)存區(qū)的任何其他進程使用。
函數(shù)5.
名稱:: shm_open
功能: 打開或創(chuàng)建一個共享內(nèi)存區(qū)
頭文件: #include <sys/mman.h>
函數(shù)原形: int shm_open(const char name,int oflag,mode_t mode);
參數(shù):
name 共享內(nèi)存區(qū)的名字
cflag 標志位
mode 權(quán)限位
返回值: 成功返回0,出錯返回-1
oflag參數(shù)必須含有O_RDONLY和O_RDWR標志,還可以指定如下標志:O_CREAT,O_EXCL或O_TRUNC.
mode參數(shù)指定權(quán)限位,它指定O_CREAT標志的前提下使用。
shm_open的返回值是一個整數(shù)描述字,它隨后用作mmap的第五個參數(shù)。
函數(shù)6.
名稱:: shm_unlink
功能: 刪除一個共享內(nèi)存區(qū)
頭文件: #include <sys/mman.h>
函數(shù)原形: int shm_unlink(const char name);
參數(shù): name 共享內(nèi)存區(qū)的名字
返回值: 成功返回0,出錯返回-1
shm_unlink函數(shù)刪除一個共享內(nèi)存區(qū)對象的名字,刪除一個名字僅僅防止后續(xù)的open,mq_open或sem_open調(diào)用取得成功。
示例:
下面是創(chuàng)建一個共享內(nèi)存區(qū)的例子:
/shm_open.c創(chuàng)建共享內(nèi)存區(qū)/
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc,char **argv)
{
int shm_id;
if(argc!=2)
{
printf(“usage:shm_open \n”);
exit(1);
}
shm_id=shm_open(argv[1],O_RDWR|O_CREAT,0644);
printf(“shmid:%d\n”,shm_id);
shm_unlink(argv[1]);
}
下面是運行結(jié)果,注意編譯程序我們要加上“-lrt”參數(shù)。
#cc –lrt –o shm_open shm_open.c
#./shm_open test
shm_id:3
四、ftruncate和fstat函數(shù)
普通文件或共享內(nèi)存區(qū)對象的大小都可以通過調(diào)用ftruncate修改。
函數(shù)7.
名稱:: ftruncate
功能: 調(diào)整文件或共享內(nèi)存區(qū)大小
頭文件: #include <unistd.h>
函數(shù)原形: int ftruncate(int fd,off_t length);
參數(shù):
fd 描述符
length 大小
返回值: 成功返回0,出錯返回-1
當(dāng)打開一個已存在的共享內(nèi)存區(qū)對象時,我們可調(diào)用fstat來獲取有關(guān)該對象的信息。
函數(shù)8.
名稱:: fstat
功能: 獲得文件或共享內(nèi)存區(qū)的信息
頭文件:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
函數(shù)原形: int stat(const char file_name,struct stat buf);
參數(shù):
file_name 文件名
buf stat結(jié)構(gòu)
返回值: 成功返回0,出錯返回-1
對于普通文件stat結(jié)構(gòu)可以獲得12個以上的成員信息,然而當(dāng)fd指代一個共享內(nèi)存區(qū)對象時,只有四個成員含有信息。
struct stat{
mode_t st_mode;
uid_t st_uid;
gid_t st_gid;
off_t st_size;
};
/shm_show.c顯示共享區(qū)信息/
#include <unistd.h>
#include <sys/type.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
int main(int argc,char **argv)
{
int shm_id;
struct stat buf;
if(argc!=2)
{
printf(“usage:shm_open \n”);
exit(1);
}
shm_id=shm_open(argv[1],O_RDWR|O_CREAT,0644);/創(chuàng)建共享內(nèi)存/
ftruncate(shm_id,100);/修改共享內(nèi)存的大小/
fstat(shm_id,&buf); /把共享內(nèi)存的信息記錄到buf中/
printf(“uid_t:%d\n”,buf.st_uid); /共享內(nèi)存區(qū)所有者ID/
printf(“git_t:%d\n”,buf.st_gid); /共享內(nèi)存區(qū)所有者組ID/
printf(“size :%d\n”,buf.st_size); /共享內(nèi)存區(qū)大小/
}
下面是運行結(jié)果:
#cc –lrt –o shm_show shm_show.c
#./shm_show test
uid_t:0
git_t:0
size:100
鍵盤緩沖區(qū)殘余信息問題
#include <stdio.h>
int main()
{
int a;``
char c;
do
{
scanf("%d",&a);
scanf("%c",&c);
printf(“a=%d c=%c\n”,a,c);
/printf(“c=%d\n”,c);/
}while(c!=’‘N’’);
}
scanf("%c",&c);這句不能正常接收字符,什么原因呢?我們用printf(“c=%d\n”,c);將C用int表示出來,啟用printf(“c=%d\n”,c);這一句,看看scanf()函數(shù)賦給C到底是什么,結(jié)果是 c=10 ,ASCII值為10是什么?換行即\n.對了,我們每擊打一下"Enter"鍵,向鍵盤緩沖區(qū)發(fā)去一個“回車”(\r),一個“換行"(\n),在這里\r被scanf()函數(shù)處理掉了(姑且這么認為吧_),而\n被scanf()函數(shù)“錯誤”地賦給了c.
解決辦法:可以在兩個scanf()函數(shù)之后加個fflush(stdin);,還有加getch(); getchar();也可以,但是要視具體scanf()語句加那個,這里就不分析了,讀者自己去摸索吧。但是加fflush(stdin);不管什么情況都可行。
函數(shù)名: fflush
功 能: 清除一個流
用 法: int fflush(FILE *stream);
#include <stdio.h>
int main()
{
int a;
char c;
do
{
scanf("%d",&a);
fflush(stdin);
scanf("%c",&c);
fflush(stdin);
printf(“a=%d c=%c\n”,a,c);
}while(c!=’‘N’’);
}
這里再給一個用“空格符”來處理緩沖區(qū)殘余信息的示例:
運行出錯的程序:
#include <stdio.h>
int main()
{
int i;
char j;
for(i = 0;i < 10;i++)
{
scanf("%c",&j);/這里%前沒有空格/
}
}
使用了空格控制符后:
#include <stdio.h>
int main()
{
int i;
char j;
for(i = 0;i < 10;i++)
{
scanf(" %c",&j);/注意這里%前有個空格/
}
}
???????高級版的取子串函數(shù),可以完成正向取子串,反向取子串,
1、調(diào)用:
substr(取出的子串,源串,起始位置,長度)
函數(shù)返回實際取到子串的長度
其中長度可以為正數(shù)(從左邊向右邊取),長度為負數(shù)(從右邊向左邊取),長度可以超過實際能取到的子串長度,函數(shù)會智能判斷,取長度范圍內(nèi)盡可能長的子串。
2、函數(shù)源代碼
C代碼
int substr(char* dchr,char *schr,int begin,int len){
//作者:myhaspl@myhaspl.com
//取子串函數(shù),dchr為取好后的子串,schr為源串,返回成功取出的子串?dāng)?shù)目,len為負數(shù),則從begin向頭部移動(正向),否則向尾部移動(反向),begin為起始位置(從1開始),len為子串長度
return rc;
}
c_預(yù)定義宏-反映編譯信息
1、 LINE:被編譯的文件中的行號
2、 FILE:編譯的日期
3、 DATE:編譯的日期(“Mm dd yyyy”)
4、 TIME:編譯的時間(“hh:mm:ss”)
5、 STDC:如果編譯器符合C標準(C89或C99),則值為1
C-#line和#error
1、
1)源代碼:
test2.c
C代碼
#line 1
int main(void){
printf(“l(fā)ine 1\n”);
printf(“l(fā)ine 2\n”);
printf(“l(fā)ine 3\n”);
printf(“l(fā)ine 4\n”);
printf(“l(fā)ine 5\n”);
printf(“l(fā)ine 6\n”);
printf(“l(fā)ine 7\n”);
printf(“l(fā)ine 8\n”);
#include "test1.c
test1.c
C代碼
#line 9 “test2.c”
#define LINUX
#ifdef WIN32
printf(“win32\n”);
#elif defined LINUX
printf(“l(fā)inux %d %s\n”,LINE,FILE);
#else
#error no flag define
//如果LINUX和WIN32沒有定義,#error會顯示錯誤信息,然后停止編譯
#endif
}
2)運行結(jié)果:
mysea@mysea-pc:~/test$ ./test2
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
linux 13 test2.c
2、#error表示停止編譯,顯示錯誤信息
3、#line 直接指定下一行的行號及文件名
1)指定行號
#line n
2)指定文件名和行號
#line n “filename”
4、源代碼的#include "test1.c"和#line 9 "test2.c"表示:test2.c和test1.c實質(zhì)屬于一個C程序:test2。
1)注意這只是標注,如果要在編譯時把test1.c包括進來,必須加上#include "test1.c
2)編譯時,編譯test2
mysea@mysea-pc:~/test$ gcc -o test2 test2.c
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的C指针原理(46)-C应用技巧(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mac版crt8.0.2打开无响应怎么办
- 下一篇: android sdk64位资源,and