提问c语言学霸的问题的问题

问个C语言的有关问题 - C语言当前位置:& &&&问个C语言的有关问题问个C语言的有关问题www.MyException.Cn&&网友分享于:&&浏览:3次问个C语言的问题main()& { char *ptr = ” Cisco Systems”;& *ptr++;& printf(“%sn”,ptr);& ptr++;& printf(“%sn”,ptr);& }& Answer:Cisco Systems& isco systems& 怎么解释?------解决方案--------------------“ Cisco Systems\0”。。这是内存中的顺序,ptr指向这段字符串的开始位置。ptr++之后指向空格后C之前的那个位置。ptr再 ++之后指向C之后。。输出从ptr指向的位置指向末尾的\0
------解决方案--------------------有什么问题吗,都很正常的吧
------解决方案--------------------这有什么问题吗?你没有改变” Cisco Systems”的内容,只是改变了ptr指向的地址而已,这本来就允许的
------解决方案--------------------首先这个代码里有错误“”应该是&&,n应该是\n,如下C/C++ code
{ char *ptr = & Cisco Systems&;
printf(&%s\n&,ptr);
printf(&%s\n&,ptr);
------解决方案--------------------main() { char *ptr = ” Cisco Systems”; *ptr++;
//取*ptr的值,然后指针加1,ptr指向字符Cprintf(“%sn”,ptr);
//打印从字符C开始的字符串ptr++;
//指针加1,ptr指向字符iprintf(“%sn”,ptr);
//打印从字符i开始的字符串}字符串“ Cisco Systems”是以空格开始的,LZ没注意到?
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有c语言问题!!
本回答由提问者推荐
var sogou_ad_id=731547;
var sogou_ad_height=160;
var sogou_ad_width=690;C语言中基础小问题详细介绍
转载 & & 作者:
这篇文章详细介绍了C语言中基础小问题,有需要的朋友可以参考一下
1、printf格式输出函数 如果格式控制说明项数多于输出表列个数,则会输出错误数据;如果输出表列个数多于格式控制说明数,则多出数不被输出。%md,m指的是输出字段的宽度。如果输出字段位数小于m,则左端以空格补齐,若大于m,则按照实际位数输出。%-md,基本同上,只不过不同之处在于,空格在右端补齐printf参数可以是常量,变量或表达式,VC++ 6.0中采用从右向左顺序求值,从左向右输出如 代码如下:int x = 5;&printf("%4d%4d%4d", x, ++x, ++x);输出的是7,7,6. 而不是5,6,7注意,不同的编译器可能输出不同结果,直接用gcc编译结果为7,7,72、0-9数字转为字符数字为m,则m+‘0'即为m的字符形式‘m'3、小写字母变为大写字母 c为小写字母,则c-'a'+'A'即为对应的大写字母4、switch如果找到匹配的case入口,则执行后面的语句,执行完语句之后,并不像if语句那样退出,如果没有遇到break语句,将逐条执行后面所有的case语句,不再进行条件判断。case入口后面的语句可以是一句,也可以是多句,并且不需要大括号。5、字符数组存储字符串当char str[5]=new {"china"};时,程序会出问题,输出的时候会在china后带乱码,这是因为china字符串后还有一位'\0',因此应该给str数组多一位。即char str[6]=new {"china"};且'\0'只表示字符串的结束,并不会输出。scanf("%s",str);不能存入空格,因为认为空格代表字符串的结束。gets(str);可以在字符串中间加入空格。puts(str);在输出字符串后自动加入换行6、字符串操作函数字符串拷贝函数:strcy(str1,str2); 将字符串str2拷贝到str1中。字符串连接函数:strcat(str1,str2); 将str2连同'\0'一起连接到str1的最后一个字符(非'\0')后面,结果放在str1中。字符串比较函数:strcmp(str1,str2); 比较str1和str2的大小,如果str1==str2,则返回0;如果str1&str2,则返回正整数;如果str1&str2,则返回负整数。字符串长度函数:strlen(str); 返回字符串str的实际长度,不包括末尾的'\0'。7、函数的参数和单向值传递函数的参数分为实参和形参。形参出现在函数定义中,在整个函数体中使用,离开函数体则不能使用。实参出现在主调函数中,进入被调函数后,实参不能被使用。形参只有被调用时才被编译系统分配内存单元,在调用结束时候,编译系统即刻释放所分配的内存单元,因此形参只在函数内部有效,函数调用结束返回主调函数后则不能再使用;单向传值:只能把实参的值传递给形参,不能把形参的值反向传递给实参,叫做单向值传递。因此,函数调用过程中,形参的值发生改变,实参的值不会改变8、数组作为参数数组名可以作为函数实参,这时候形参可以是数组或者指针。且形参是一维数组时候可以不指定长度。形参是二维数组时候,第一维大小可以省略,要指定第二维的大小。9、变量的存储方式(1)局部变量局部变量在每次函数调用时,系统会在内存的动态存储区为他们重新分配内存单元,随着函数的频繁调用,某个变量的存储位置会随着程序的运行不断变化,所以未赋值的局部变量的值是不确定的。函数中的局部变量不能作为返回值,因为函数结束后,局部变量要被回收。(2)static类型静态变量在编译的时候被分配内存、赋初值,并且只会被赋初值一次。未赋初值的静态变量,系统自动赋初值0(或'0')。静态变量在内存静态存储区占用固定的内存单元。即使它所在的函数调用结束,也不会释放存储单元,其值也会继续保留,下次调用,会继续使用该值。静态变量分为静态局部变量和静态全局变量,静态全局变量就是定义在函数体外的静态变量,静态局部变量就是定义在函数体内的静态变量。如下: 代码如下:#include&stdio.h&void f(){&&& static int a=0; //编译时被赋初值,且整个过程只被赋初值一次&&& ++a;&&& printf("%-2d",a);}main(){&&& f();&&& f();&&& f();}以上程序的输出结果为1 2 3因为对static变量赋初值是在编译时完成,而且只赋值一次,之后在调用函数不会执行赋初值操作,因此输出1 2 3 ;若去掉static关键字,那么结果就会变为1 1 1 ;由此看出,函数反复调用多次,局部变量每次都会被赋初值,而静态变量只是在第一次被调用的时候赋初值。此处特变注意:java中是没有静态局部变量的,只会有针对类的静态全局变量。(3)寄存器类型定义形式: register 数据类型 变量名;寄存器类型局部变量的作用域、生存期与局部变量相同。寄存器的个数有限,寄存器的存储数据位数有限,所以寄存器类型的变量不能太多,而且有整型变量和字符型变量才能被定义为寄存器类型的局部变量。现在的优化系统可以自动的判断把相关变量存到寄存器中。(4)外部变量10、编译预处理#include&文件名&和#include"文件名"的区别是:使用尖括号时,编译预处理程序只在系统指定的文件夹中寻找;而使用双引号,编译预处理程序首先在当前文件所在的文件夹中寻找,如果找不到,则在系统指定的文件夹中再寻找。11、&和*优先级都属于第二级,从右向左运算12、*与++、--运算符都属于第二级,从右向左计算*p++& 等价于& *(p++)*++p& 等价于& *(++p)13、[& ]和*[& ]优先级高于*13、二维数组的行地址和列地址int a[2][2]={1,2,3,4};则a为首地址,第一行首地址;*a和a[0]都是第一行第一个元素的地址a+1为第二行行地址*(a+1)为第二行第一个元素地址,a[1]也为第二行第一个元素地址14、指向数组的指针变量(数组指针)int *(p) [4];表示一个指向含有4个int元素的数组的指针。(1)p指向一维数组的首行地址 代码如下:main(){&&& int a[2]={1,2};&&& int (*p)[2];&&& p=&a;//p是指向数组的指针,即行指针,因此要用&a给其赋值,&a为数组地址&&& printf("%d\n",**p);//取第一个元素,其中p为行地址,*p为元素地址,**p为元素值&&& printf("%d\n",*(*p+1));//取第二个元素&&& //也可以如下取值&&& printf("%d\n",(*p)[0]);//(*p)可以取代a&&& printf("%d\n",(*p)[1]);}(2)p指向二维数组的首行地址 代码如下:main(){&&& int a[2][2]={1,2,3,4};&&& int (*p)[2];&&& p=a;//p指向二维数组的首行地址&&& printf("%d\n",**p);//*p是元素的地址,**p则为元素内容&&& printf("%d\n",*(*(p+1)+1));}15、指针数组int *p[4];表示一个数组中含有4个int型指针。char *p[4];表示一个数组中含有4个char型数组,或则4个字符串16、二维数组中的各个地址int a[2][3];则a为首行地址,*a为首行第一个元素地址,**a为首行第一个元素的值a+1为第二行地址,*(a+1)为第二行第一个元素的地址,**(a+1)为第二行第一个元素的值*(a+1)与a[1]等价:都代表第二行第一个元素的地址例子: 代码如下:main(){&&& int a[2][2]={1,2,3,4};&&& printf("a=%d\n",a);&&& printf("*a=%d\n",*a);&&& printf("**a=%d\n",**a);&&& printf("*a+1=%d\n",*a+1);&&& printf("a+1=%d\n",a+1);&&& printf("a[1]=%d\n",a[1]);&&& printf("a[1]+1=%d\n",a[1]+1);&&& printf("*a[1]=%d\n",*a[1]);}17、字符指针变量在接受输入字符串时,必须先开辟存储空间char *scanf("%s",cp);以上是错误的。可以改为:char cp[20];scanf("%s",cp);或者char *cp,str[20];cp=scanf("%s",cp);总之,一定要先开辟空间,再接受字符串18、c和c++中的返回值不能是数组,java返回值可以是数组19、指针函数和函数指针指针函数:int * function();函数指针: 代码如下:int (*p) ();int max(int a,int b);p=int a=(*p)(2,3);20、关于变量的生命周期函数中定义的局部变量是不能作为返回值的,因为函数结束后,局部变量就被回收了。21、结构体结构体中可以嵌套结构体,但不能是其本身。且成员结构体的定义必须在主结构体之前。22、mallocmalloc函数位于stdlib.h中,函数原型为void * malloc(unsigned size);eg: struct student *p=(struct student *)malloc(sizeof(struct student));因为malloc返回的是一个void类型的指针,所以要强制转换。23、free该函数原型为void& free(void * ptr)释放有指针ptr指向的动态分配的内存空间。为保证动态存储区的有效利用,当某个存储空间不再使用时,就应该及时释放它。24、结构体和共用体(1)结构体结构体可以作为函数的参数和返回值。结构体只有在初始化的时候才能直接用大括号{}形式赋值;当先声明,后赋值时候,就只能单个元素赋值,不能再用大括号形式了。这个跟数组的赋值类似。举例如下 代码如下:struct student{&&&&&& char *};struct student stu={1,'typ'};//是正确的但是下面的是错误的 代码如下:struct student stu;stu={1,"typ"};//是错误的此时这能stu.bh=1;stu.name="typ"(2)共用体共用体不能作为函数的参数和返回值共用体不能同时存放,每一时刻只能存放一个成员,以最后一次存放的成员为有效成员。共用体的大小是最大元素所占用的大小;共用体可以出现在结构体类型中,反之,结构体也可以出现在共用体的类型中25、枚举类型 代码如下:enum color {red,green,blue};enum color c=int i=//值为026、类型标识符的重定义c语言中用关键字typedef来声明新的类型名typedef int INTEGER;INTEGER x,y;等价于int x ,又比如结构体定义: 代码如下:typedef struct{&&&&&& char name[10];&&&}student& stu1, stu2, *s;另外,typedef只是进行类型重定义,只是为该类型命名一个别名,并不产生新的数据类型27、位运算包括(与、或、异或、取反)。其中,位运算符进行运算时,数都是以补码形式参加运算,且符号位参与运算。异或:相同为0,不同为1a^a=0;a^0=a;a^~a=1;此处可以用异或来实现两数的交换a=a^b;b=b^a;a=a^b;这样避免引入临时变量28、移位运算(1)a&&b,表示a的二进制值左移b位(2)a&&b,表示a的二进制值右移b位移位运算具体实现有3种形式:(1)循环移位:移入的位等于移出的位(2)逻辑移位:移出的位丢失,移入的位取0(3)算术移位:移出的位丢失,左移入的位取0,右移入的位取符号位,符号位保持不变C语言的移位运算与具体的C编译系统有关,如VC++6.0采用的是算术移位注意:移位操作并不会改变原操作数的值。例如a&&2运算后,a的值保持不变,除非通过赋值a=a&&2来改变a的值。29、文件(1)C语言中文件是字节流文件.(2)C中为用户定义的文件类型是FILE,FILE文件类型是结构体类型,FILE结构是用关键字typedef定义出的一种结构。 代码如下:struct& _iobuf{char * _int _char *int _int _.........};typedef struct& _iobuf& FILE;(3)文件打开与关闭文件指针 = fopen("文件路径\\文件名", "文件操作方式");操作方式分为r,w,a,r+,w+,a+如果fopen打开失败,则返回NULL如果缓冲区未满512B,那么不会写到磁盘中,万一程序异常终止,则缓冲区中数据丢失,导致文件不完整。只有对打开文件执行关闭操作时,才能强制把缓冲区中不足512B的数据写到磁盘文件中,保证文件的完整性。fclose函数用来关闭文件fclose(文件指针);返回值是一个整数值,若为0,表示正常关闭,否则表示无法正常关闭文件。(4)文件的输入和输出读写一个字符:char fgetc(文件指针);EOF fputc(字符,文件指针)读写一个字符串:fgets(字符串s,读入字符个数n,文件指针)---&在中途遇到\n或者EOF停止,读n-1个字符,在末尾加'\0';fputs(字符串,文件指针)---&字符串的结束标记不会写入文件格式化读写:fscanf(fp, "%d%s", &i, s)---&从文件中读取数据保存到变量;fprintf(fp, "%d%c", j, c)---&按指定格式向文件写入数据成块读写:fread(buffer,size,count,fp)和fwrite(buffer,size,count,fp)buffer是一个指针,fread()中表示存放“输入数据”的变量首地址,fwrite()中表示存放“输出数据”的变量首地址size表示数据块的字节数count表示数据块个数fp文件指针返回值都是count值(4)其他文件操作的函数feof(fp)判断文件的末尾标志,到达末尾返回1,否则返回0rewind(fp)用于定位,是文件的位置指针返回文件开头。fseek(fp, offset, base)用来控制文件内部位置指针移动。base是位置移动的基准点。offset是偏移量ftell(fp)用于获取位置指针的位置,相对于文件开头。
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具C语言问题10-土地公问答
C语言问题10
C语言问题10
【习题8.044】请编写一个函数func,通过略去非数字字符,将字符串
s转换为一个整数(不得调用C语言提供的将字符串转换为整数的函数)。
**********/
long func(char *s)/* s是一个数字字符串的地址,函数返回值为由s含有的数字字符转换得到的数(包含...【习题8.044】请编写函数func通略非数字字符字符串s转换整数(调用C语言提供字符串转换整数函数)**********/long func(char *s) /* s数字字符串址函数返值由s含数字字符转换数(包含负数情况) i*/{int sum=0,i=0,j=1,k;for(i=0;s[i]!='\0';i++)k=i-1;for(k=i-1;k&=0;k--)if((s[k]&='0')&&(s[k]&='9')){sum=sum+s[k]*j,j=j*10;}}展开
#include&longfunc(char*s){intsum=0;for(inti=0;s[i]!='\0';i++){if(s[i]&='0'&&s[i]&='9')sum=sum*10+(s[i]-'0');}}intmain(){chars[100];scanf(&%s&,s);longnum=func(s);printf(&%ld\n&,num);return0;}
其它类似问题
其它人正在问的问题非常经典的C语言趣味题目
转载 & & 作者:
在这个网站上发现一套很有趣的C语言测试题,如果你招聘C语言相关开发人员,或者正在学习C语言,很值得做一做
在这个网站上发现一套很有趣的C语言测试题,如果你招聘C语言相关开发人员,或者正在学习C语言,很值得做一做。
如果没有做,下面内容暂时不要看,最好自己先完成一遍。
OK,假设你做的答案没有完全正确,那你可以继续看下去了,否则,后面内容对你来说就是小菜一碟,不值得看。
#include &setjmp.h&static jmp_int main(void){volatile int b = 3;if (setjmp(buf) != 0){printf("%d\n", b);exit(0);}b = 5;longjmp(buf, 1);}
输出结果为A)3 B)5 C)0 D)都不是
答案为B,也就是输出5。
关键点在于理解setjmp以及longjmp,( )第一次运行到setjmp,会设置jmp_buf,然后返回0。当调用longjmp时,会把longjmp里面的非0值作为setjmp的返回值返回(如果longjmp的value参数为0,setjmp恢复后返回1,也就是当恢复到setjmp存储点的时候,setjmp一定不会返回0)。
setjmp-longjmp组合的用处类似于游戏中的存盘读盘功能,经常被用于类似C++的异常恢复操作。
struct node{};struct node s = { 3, 5, 6 };struct node *pt = &s;printf("%d\n", *(int*)pt);返回结果为3,这个算是比较简单,pt为指向结构s的指针,然后将pt转换为int指针,进行dereference,取出一个int值,那就是结构中第一个数。
我们将题目改动一下,如下代码
代码如下:struct node {
}; struct node s = { 3, 5, 6, 99 }; struct node *pt = &s; printf("%X\n", *(int*)pt);需要注意的是一般32位C编译器都认为char是8bit,short是16bit,int为32bit,所以node在内存中应该正好是对齐的,也就是abc这几个成员之间没有空隙。最终结果应该为60503,如果不是,欢迎你告诉我你具体的编译环境以及硬件配置。
代码如下:int foo(int x, int n){ int val = 1; if (n & 0) { if (n % 2 == 1) val *= val *= foo(x * x, n / 2); }
}这道题其实最简单的办法就是在纸上做一个推演计算,一步一步跑一下,就能得到答案了,这里面没有任何复杂的C语言概念。
代码如下:int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int*)(&a + 1); printf("%d %d\n", *(a + 1), *(ptr – 1));这道题考的其实是指向数组的指针,&a是一个隐式的指向int [5]数组的指针,它和int* ptr是不一样的,如果真要定义这个指针,应该是int (*ptoa)[5]。所以ptoa每一次加一操作都相当于跨越int a[5]的内存步长(也就是5个int长度),也就是说&a + 1其实就是指向了a[5]这个位置,实际上内存里面这个位置是非法的,但是对ptr的强制转换导致了后面ptr-1的内存步长改为了1个int长度,所以ptr-1实际指向了a[4]。至于*(a+1)没什么好说的,值就是2。
代码如下:void foo(int[][3]); int main(void) { int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; foo(a); printf("%d\n", a[2][1]); return 0; } void foo(int b[][3]) { ++b; b[1][1] = 9; }其实和前一题有异曲同工之妙,++b的步长实际上是3个int,也就是++b运算以后,b指向{4,5,6}这个数组的开始,而b[1]就是{7,8,9}, b[1][1]实际上就是8这个值也就是main函数中的a[2][1].
代码如下:int a, b, c, a = 3; b = 5; c = a, d = (a, b); printf("c=%d ", c); printf("d=%d\n", d);这个其实有两个C语言知识点,一个是等号操作符优先级高于逗号操作符,另一个是逗号操作符相当于运算逗号前半部后半部的表达式,然后返回后半部表达式的值。所以c等于a(先计算等号),而d等于b(逗号表达式返回b)。
代码如下:int a[][3] = {1, 2, 3, 4, 5, 6}; int (*ptr)[3] = printf("%d %d ", (*ptr)[1], (*ptr)[2]); ++ printf("%d %d\n", (*ptr)[1], (*ptr)[2]);依然是2维数组相关题目,ptr为指向int [3]数组的指针,首先指向a[0],所以(*ptr)[1], (*ptr)[2]就是a[0][1], a[0][2].然后++ptr,相当于ptr指向了a[1],这时得到的是a[1][1],a[1][2],所以结果就是2,3, 5, 6。
代码如下:int *f1(void) { int x = 10; return &x; } int *f2(void) { int * *ptr = 10; } int *f3(void) { int * ptr = malloc(sizeof *ptr); }这里考的是返回一个指针的问题,一般来说返回指针的函数,里面一定有malloc之类的内存申请操作,传入指针类型,则是对指针指向的内容做修改。如果想修改指针本身,那就要传入指针的指针。
代码如下:int i = 3; j = sizeof(++i + ++i); printf("i=%d j=%d\n", i, j);这道题考的内容其实就是sizeof,我在这篇文章里提到过 sizeof如果计算表达式,那么表达式是不会做计算的,也就是不管加加减减,sizeof就是针对i计算大小。在32位机器上,这个j应该为4。
我将代码扩展了一下,看看大家能不能想到结果:
代码如下: int j = sizeof ( m + n); int k = sizeof ( n + n); int l = sizeof ( m); int l2 = sizeof (m * m); int l3 = sizeof (m + dn); int l4 = sizeof (m + m);第十题:
代码如下:void f1(int*, int); void (*p[2])(int*, int); int main(void) { int a = 3; int b = 5; p[0] = f1; p[1] = f1; p[0](&a, b); printf("%d %d ", a, b); p[1](&a, b); printf("%d %d\n", a, b); return 0; } void f1(int *p, int q) { int tmp = *p; *p = q = }函数指针的数组p勉强算是一个知识点,另外一个知识点就是第八题提到的,对于int q这样的参数,是不会修改其内容的。而*p则可修改p指向的内容。
第十一题:
代码如下:void e(int); int main(void) { int a = 3; e(a); putchar(‘\n'); return 0; } void e(int n) { if (n & 0) { e(–n); printf("%d ", n); e(–n); } }这道题自己debug一下就完全明白了,主要知识点就是递归调用,另外前置后置自减操作的返回值问题。
第十二题:
代码如下:typedef int (*test)(float*, float*); 也是经常出现的一类题,对复杂的指针定义做解析,实际上K&R里面(5.12)也有介绍该如何解读。不熟悉的朋友可以试着练习练习标准库中的bsearch,qsort以及signal函数。
第十三题:
代码如下: char buf[10] = {1, 2, 3, 4, 5, 6, 9, 8}; p = (buf + 1)[5]; printf("%d\n", p);这道题我在 也提到过相关知识点,也就是p实际指向*(buf + 1 + 5),写的更诡异一些就是p=5[buf +1];也是同样结果。
第十四题:
类似十三题,也是把数组弄得有些诡异,(p += sizeof(int))[-1];相当于*(p + sizeof(int) + (-1))。
第十五题:
代码如下:int ripple(int n, …) { int i, j, va_ k = 0; j = 1; va_start(p, n); for (; j & ++j) { i = va_arg(p, int); for (; i &= i – 1) ++k; }
} int main(void) { printf("%d\n", ripple(3, 5, 7)); return 0; }这道题也是两个知识点,一个是可变参数函数定义以及如何实现,va_arg会把5,7依次取出来。另一个知识点是i &= i-1,实际上是计算了i二进制形式中1的个数,每次计算都会消减掉最低有效位上的1。比如7二进制表示为111。i &= i –1的计算结果依次为110,100, 000 (也就是0)。在hacker's Delights这本书里介绍了很多类似技巧。
第十六题:
代码如下:int counter(int i) { static int count = 0; count = count +
} int main(void) { int i, for (i = 0; i &= 5; i++) j = counter(i); printf("%d\n", j); return 0; }只要了解静态局部变量的真正内涵,这道题就是小菜一碟碟碟碟碟碟。。。。。。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具}

我要回帖

更多关于 数据结构 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信