开发中遇到了需要传参数给main函数的问题,不常用,也就不记得了,特意查了一下,参考这里。
一个简单的C语言例子,如下(例子来源于参考网站):
int main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) printf("%s%s", argv[i], (i < argc-1) ? " " : ""); printf("\n"); return 0; }
程序编译后,添加参加如:c:\demo.exe hello,world
程序就会运行出来结果:
hello,world
C语言约定:argv[0]的值是启动该程序的程序名,因此argc的值至少为1,如果argc的值是1,说明程序名后面没有命令行参数。
Read More →参考:http://www.cnblogs.com/lin1270/archive/2013/04/17/3025831.html
多线程调试直接崩溃,没有堆栈调用,很难查问题,只有一个错误提示框,类似于“关于 xxxx.exe 中的 0xxxxxxxx 处最可能的异常: 0xC0000005: 读取位置 0xxxxxxxx 时发生访问冲突”,参考上述站点,把堆栈调出来的方法,MARK:
工具栏上的【调试】->【异常】,把图上显示的【引发】勾上即可。
Read More →一直困惑了很久的一个问题,今天终于解决了,参考:http://blog.csdn.net/daniel_ice/article/details/6857019
#include <stdio.h> int a[2] = {1,2}; int main(){ printf("a = %p\n", a); // I printf("&a = %p\n", &a); // II printf("a + 1 = %p\n", a + 1);// III printf("&a + 1 = %p\n", &a + 1);// IV return 0; } //结果如下(Windows): //a = 01137034 //&a = 01137034 //a + 1 = 01137038 //&a + 1 = 0113703C
在C中, 在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址。 它的类型取决于数组元素的类型: 如果它们是int类型,那么数组名的类型就是“指向int的常量指针“。
看到这里我想应该就知道为什么 会有I 和 III式的结果了。
对于II 和 IV 则是特殊情况,在《C和指针》p142中说到,在以下两中场合下,数组名并不是用指针常量来表示,就是当数组名作为sizeof操作符和单目操作符&的操作数时。 sizeof返回整个数组的长度,而不是指向数组的指针的长度。 取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量的指针。
所以&a后返回的指针便是指向数组的指针,跟a(一个指向a[0]的指针)在指针的类型上是有区别的。
Read More →参见搜索做的总结,原文地址如下:http://blog.csdn.net/daiyutage/article/details/8605580
一直有一个疑惑,字符串常量放在哪个存储区呢?比如:
char *pstr = "hello world!";
这里,"hello world!"是一个字符串常量,pstr是在栈中的变量,字符串常量(hello world!),如何存储?举个例子,比较清晰。
//main.cpp int a = 0; //全局初始化区 char *p1; //全局未初始化区 main() { int b; //栈 char s[] = "abc"; //栈 char *p2; //栈 char *p3 = "123456"; //123456\0在常量区,p3在栈上。 static int c = 0; //全局(静态)初始化区 p1 = (char *)malloc(10); p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。 strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 }
上面例子说得比较全了,之前还以为char s[] = "abc"; 这里的abc也是在常量区,too young, too simple啊。
下面总结的一些常识,很形象,很生动,MARK一下。
Read More →逗号表达式,不常用,安全软件编码中也不允许使用,百科的解释比较到位:
c语言提供一种特殊的运算符,逗号运算符,优先级别最低,它将两式联接起来,如:(3+5,6+8)称为逗号表达式,其求解过程先表达式1,后表达式2,整个表达式值是表达式2的值,如:(3+5,6+8)的值是14。(a=3*5,a*4)的值是60。
看两个例子就能明白,这两个例子都是告诉我们,逗号运算符的优化级比赋值号还低。
main() { int a, b, c, d; a = 3; b = 5; c = a, b; d = (a, b); printf(" c = % d & quot; , c); printf(" d = % d & quot; , d); } //结果是 3 5
main() { int x, y, z; x = y = 1; z = x++, y++, ++y; printf("%d,%d,%d\n", x, y, z); } //结果是 2 3 1Read More →
一直忙于干活,很多知识都遗忘了,遇到一段代码,发现自己的基础太令人捉急了,代码类似于:
main() { int a[5] = {1, 2, 3, 4, 5}; int *ptr = (int *)(&a + 1); printf("%d %d" , *(a + 1), *(ptr - 1)); }
结果应该是2 5,原因在于(int*)(&a+1)这里。
2013/12/10 22:51 update:
指针和数据很多时候混用,但不代表两者相同,另外,很重要的一点,如果一个数组声明为指针时,定为成数组时,如下:
extern int *a;//声明 int a[0] = {0,1};//定义
在使用extern的文件中,若使用a[0]的方式来访问,就会出现错误,原因是编译以声明作为编译的依据,定义可以看作是一种特殊的声明,是分配内存,甚至初始化的功能。用指针去访问数组,存在二次寻址的过程,但是例子中的指针a并不存在一个额外的内存地址用来存放指针变量,所以编译器会把a[0]翻译为,先从a的内容中取内容0,再去寻找存放在地址0内的内容,这显然是不正确的,找不到地址为0的内存。
Read More →研究编译器优化(选择的是完全优化)时,发现的问题,编译不通过,万能的Google一下子就搜到了,看来是常见的问题,参考:
http://blog.csdn.net/mdjtf/article/details/5617292
程序运行时弹出了一个新窗口叫做【输出】,里边写着生成日志保存某个位置,基本是在工程目录下的Debug,打开内容有:
cl: 命令行 error D8016 :“/O2”和“/ZI”命令行选项不兼容
项目 : error PRJ0002 : 错误的结果 2 (从“C:/Program Files/Microsoft Visual Studio 9.0/VC/bin/cl.exe”返回)。
经查是调试信息格式的用于“编辑并继续”的程序数据库(/ZI),改成禁用,继续。
新的错误:cl: 命令行 error D8016 :“/O1”和“/RTC1”命令行选项不兼容,此时将代码生成的基本运行时检查为默认值,就可以了。
看到这两个函数,不认识,没用过,赶紧MARK,参考:
http://blog.csdn.net/chenyiming_1990/article/details/8683413
http://blog.codingnow.com/2010/05/setjmp.html
setjmp和longjmp函数是非局部跳转语句。非局部指的是,这和C语言常见的goto不一样,goto语句在一个函数内实施的跳转,而setjmp和longjmp是在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。使用这两上函数比goto还要容易出错,<u>所以不会用在安全软件上,而且也不是C89的标准。</u>
#include <setjmp.h> // 返回值:若直接调用则返回0,若从longjmp调用返回则返回非0值的longjmp中的val值 Int setjmp(jmp_buf env); //调用此函数则返回到语句setjmp所在的地方,其中env 就是setjmp中的 env,而val 则是使setjmp的返回值变为val。 Void longjmp(jmp_buf env,int val);
当检查到一个错误时,调用longjmp函数(两个参数),第一个参数就是在调用setjmp时所用的env,第二个参数是具有非0值的val,它将成为从setjmp处返回的值。<strong>使用第二个参数的原因是对于一个setjmp可以有多个longjmp。</strong>
下面这个例子简单地讲述了这两个函数是如何使用的:
#include <stdio.h> #include <setjmp.h> static jmp_buf buf; void second(void) { printf("second\n"); // 打印 longjmp(buf,1); // 跳回setjmp的调用处 - 使得setjmp返回值为1 } void first(void) { second(); printf("first\n"); // 不可能执行到此行 } int main() { if ( ! setjmp(buf) ) { first(); // 进入此行前,setjmp返回0 } else { // 当longjmp跳转回,setjmp返回1,因此进入此行 printf("main\n"); // 打印 } return 0; } //程序将输出: //second //mainRead More →