#define e
#else
#define k
#endif
预定义
#define a(b) #b // 一个#号说明b被当成一个字符串 结果为 "b"
#define a(b) s##b //两个#号表示b被当成字符串且与字符s链接
#define g() do{ }while(0) //复杂定义使用,保证任何场合都适用
前后加加的区别:
a+++b;//12 a++ +b ++后为执行后加 ++前为执行前加
int a = 5, b = 7;
++a+b;//13
区分定义类型于定义变量
int*a;//声明变量
int b=10;//定义变量
定义返回值为某类型的函数
typedef void (*a)(void *b);//定义一个返回值为void的函数 void hi(void *m){ printf("%s","hi"); }; a b=&hi; void *k=(void *)(0); b(k);
非本文件变量使用:
extern int a;//尽量少用...
struct 的声明可以省略typedef
数组误区:
{1,2},
{3,4}
};
int *b[2]={
"12",
"34",
};
a 表示一个存储着数组的数组,所以a[0]代表的是一个数组,所以sizeof(a[0])是一个数组的大小,sizeof(a)表示存储所有数据的大小
b表示一个存储一个指针的数组,所以a[0]代表一个指针,所以sizeof(a[0])是一个指针大小,sizeof(a)表示一个存储所有指针的总大小
误区二:
int a[]={1,2};
a为指向数组的名
int *b={1,2};//错误
a是指向整数的指针
int *c[]={1,2};//错误
a是指向整型数组的名,如:int *c[]={a};
数组的名有类似指针的功能,但本身是不能更改的
int b[]={1,2,3};
int *k=b;
printf("%d",b[0]);
printf("%d",*(b+1));//数组不是指针,不能自加操作
printf("%d",*k);
printf("%d",*++k);
指针:指向一个内存位置
数组名:数组名存放第一个数组的内存位置,但同时还包含有整个数组的信息
{
'a',
'b',//丢弃
'c'//丢弃
},
{
'a',
'b',//丢弃
'c'//丢弃
},
};
printf("%d",sizeof(a));//2
printf("%d",sizeof(a[0]));//1 为a
va_list arglist;
va_start(arglist,n);//设置头参数及参数数量
int i;
for(i=0;i<n;i++){
printf("%d",va_arg(arglist,int));//这就是传入的参数
}
va_end(arglist);
}
//调用
te(8,2,1,1,1,1,1,11,2312);//第一个参数是指后面共有几个参数
typedef int (*nn)();//定义函数指针
int (*tt)();//声明函数指针
nn abk;
abk =&ab;
tt=&ab;
printf("%d",((int (*)())tt)());
char b[10]="test";
//b可以赋值给A,因为b的数据在栈区,指针可以指向栈区
a=b;
char *c="test";
char d[10];
char *e[10];
*e[0]='a';//错误,可能修改于未知的内存数据
d=c;//错误,数组不能指向静态区数据
*a="12";
int (*c[2])d();
总结:指针定义后如果没有初始化,其指向位置是不确定的,此时不应该给指针赋值,最好在指针定义时初始化,不然在指针没指向任何元素前不要使用指针
指针定义后不能初始化是因为定义后他们是指针并非值
指针的自增或自减 或加值减值:移动的位置与指针的类型有关,加减的数量是类型大小的倍数,自增或自减之后当前指针的位置已变
打印输入后字符还在缓冲区,使用:
fflush(stdout);//fflush(stdin);
//stdio.h
强制输出,C++中endl搞定,还是c++方便
字符串指针更改字符问题:
此值不能修改,因为该指针指向的是常量,数据在静态区,非栈区
可以修改,因为数据在栈区
只要非静态的数据,均可以使用指针来修改,例如:
char * b =(char *)malloc(strlen(*a)+1);
b[0]='f';
strcpy(b,a);
关于malloc,calloc,realloc,free:
void * m=calloc(10);//分配10个字节空间并置于0
void * m=calloc(10,10);//分配连续10个10个字节的空间
realloc(m,-10);//指定空间加减空间
free(m);
得到
memset(m,0,sizeof(m));//申请的内存最好重置
初始化的时候也可以使用:
现在为栈区数据
malloc 内存没申请够一样可以赋值,只是覆盖掉了不相关的内存,可能会造成运行时错误
static void a();//限制为本文件内函数
结构体大小(内存对齐规则)
结构体大小必须是结构体中最大的类型的倍数
结构成员的起始位置必须是该类型(基本数据类型)的大小的倍数
结构体省内存方法
成员小的放置于前面,相同大小的尽量放置于一块,成倍数的放置于相邻位置
计算文件大小:
int filelen;
fseek(f,0,SEEK_END); //文件指针移到末尾
filelen=ftell(f); //获得文件当前指针位置,即为文件长
fclose(f);
读取文件成字符串:
int filelen;
int i=0;
char * buf=NULL;
fseek(f,0,SEEK_END); //文件指针移到末尾
filelen=ftell(f); //获得文件当前指针位置,即为文件长度
rewind(f); //将文件指针移到开头,准备读取
buf=malloc(filelen+1); //新建缓冲区,存储独处的数据
for(i=0;i<filelen+1;i++)
buf[i]=0;
fread(buf,filelen,1,f);
fclose(f);
使用MYSQL: (for cdt)
添加库:c/c++ build -> settings -> mingw c linker -> miscellaneous ->other objects 增加libmysql.lib (安装了MYSQL后在mysql的lib目录下)
引入头文件:#include "../include/mysql.h" (在mysql安装目录下可以找到)
MYSQL_RES *result;
MYSQL_ROW row;
mysql_init(&mysql);
if (!mysql_real_connect(&mysql, "localhost", "test", "test", "test", 3306, NULL, 0))
{
printf("/n数据库连接发生错误!");
exit(1);
}
if (mysql_query(&mysql, "SELECT * FROM ko_music_info")){
printf("/n数据库查询发生错误");
}else{
result = mysql_store_result(&mysql);
if (mysql_num_rows(result)){
int numRows = mysql_num_rows(result);
int numFields = mysql_num_fields(result);
printf("\n- %d rows,field %d", numRows, numFields);
int j = 1;
while (row = mysql_fetch_row(result)){
printf("\n ------------- %d --------------------\n", j);
int i;
for (i = 0; i < numFields; i++){
fprintf(stdout, " %s", row[i]);
}
j++;
}
}
mysql_free_result(result);
}
mysql_close(&mysql);
CURL使用:
下载curl源码:
进入lib目录下编译库文件: mingw32-make -f Makefile.m32
引入头文件:#include "../curl/include/curl/curl.h" (curl源码包里)
CURLcode res;
size_t a;
curl=curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://www.qq.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
抓取为字符
printf("s%",ptr);
return nmemb;
}
void * get_url(*url){
CURL *h;
curl_global_init(CURL_GLOBAL_ALL);
h=curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL,url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
FILE * file=fopen("websource.html","a+b");
curl_easy_setopt(curl,CURLOPT_WRITEDATA,file);//传入处理获得字符的句柄,文件字符或其他等等
curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(file);
return ((void *)0);
}
判断WIN还是LINUX
#include <windows.h>
#define sleep(n) Sleep(1000 * (n))
#else
#include <unistd.h>
#endif
返回VOID指针
void * pth(){}
文件存储复杂数据类型
int a;
int b;
} b;
b k[2]={
{10,8},
{2,4}
};
FILE *file;
file=fopen("a","w+b");
fwrite(&k,sizeof(b),2,file);
fclose(file);
FILE *rfile;
b *rk;
rk=(b*)malloc(sizeof(b)*2);
rfile=fopen("a","r+b");
fread(rk,sizeof(b),2,rfile);
fclose(rfile);
printf("%d",(++rk)->a);
printf("%s","hi");
fflush(stdout);
sleep(10);
return (void *)0;
}
pthread_t t;
/*pthread_t *t;//如果定义的是指针,记得分配空间
t=(pthread_t *)malloc(sizeof(pthread_t));*/
pthread_create(t,NULL,(void *) abc,NULL);
pthread_join(*t,NULL);//一定要处理,否则无效果
//pthread_exit(t);
有定义,无实现错误:
error: conflicting types for *
函数未在main之前声明.
遍历字符串,因为字符串以0结尾
char *a="aaaa";
char p;
while(p=*a){
//使用p
a++;
}
数组作为函数参数时,传递的只是其指针,所以
int t(char *a);跟int t(char a[])是相同的
注意:
char vt[100];//sizeof(t);=100
int t(char *vt){sizeof(vt)//4,指针长度}
enum 是整形,且不会有类型验证
enum{HI} a; enum{GOOD}b;
b=HI;//程序是正常的,但不建议这样用.
字符串操作函数均指有实体字符的值
如:char a[5]="abc"; char b['2']="1"; strcat(a,b);//a=abc1 而不是abc\01;且后面通常都会加\0结束符.
函数参数传递指针时,函数为为指针的拷贝
所以要修改指针时,需要传递指针的指针
GCC 编译生成汇编
gcc -S cfile
GCC 编译不连接文件
gcc -c cfile
GCC 编译生成优化汇编
gcc -O2 -S cfile
.o 文件反编译
objdump -d ofile.o
其他详细:http://blog.csdn.net/howdyhappy/article/details/2329101