[置顶] C语言学习及项目开发所遇问题总集(一)---Mr.Zhang

1.指针函数做参数---Mr.Zhang
// 指针函数做参数.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
//#include "stdio.h"
#include "iostream"
using namespace std;
int main(int ,int ,int(*p)(int ,int))
{
 int x,y;
 int s;
 int max(int,int);  //声明没用变量,指针函数做参数时没用变量
 p=max;      //指针p指向max函数
 cout<<"请输入两个整数:"<<endl;
 cin>>x>>y;
     s=(*p)(x,y);
 cout<<s;
 cout<<&x<<endl;
 return 0;
}
int max(int a ,int b)    //需要定义参数变量
{
 int c;
 if(a>b) c=a;
 else c=b;
 return c;
 
}
2.const 应用---Mr.Zhang
作用:在程序内部定义为const,内部程序定义的变量值将不可改变。
const与常量的区别在于const定义的是变量,是可改的,在外部可以对const变量进行改变。

const应用在:一个程序由多人开发,定义的变量可能发生冲突,当const变量后,编译时可以提示
编程者此变量无法修改。
3.指针数组应用---Mr.Zhang
多用于指向若干个字符串。(c语言中无字符串类型,定义多个字符串需要用二维数组,
但是声明二维数组时需要对列进行初始化,但是字符串的长度不一样,这样难免产生内存的浪费!)
4.指向数组的指针---Mr.Zhang
// 指向数组的指针.cpp : 定义控制台应用程序的入口点。
//
//用指向数组的指针及指向指针的指针进行字符串的排序
#include "stdafx.h"
#include "iostream"
#define N 4
using namespace std;
int sort (char * p[],int n);
int print (char * p[],int n);
int _tmain(int argc, _TCHAR* argv[])
{
 char * string="i love China!";
 char * name[N]={"vb","net","java","c++"};
    for(int i=0;i<N;i++){
  cout<<"输入的字符串为"<<endl;
  cout<<name[i]<<endl;
 }
 sort(name,N);
 print(name,N);
 char * *o;   //可以将char * *o理解为:*o是指针和数组name[i]一样o表示name[i]地址
 for(int i=0;i<N;i++){
  o=name+i;
  cout<<"shuchu:"<<*o<<endl;     //*o表示二层指针地址,类似于string也是地址,指向二层指针首个char型数据。
 }
 cout<<string<<endl;    
 cout<<*string<<endl;

 return 0;
}
int sort(char * p[],int n)
{
 char *t;
 int k;
 for(int i=0;i<n-1;i++){
  for(int j=i+1;j<n;j++){
   if(strcmp(p[i],p[j])>0){
    k=i;
    if(k!=j){
     t=p[i];
     p[i]=p[j];
     p[j]=t;
    }
   }

  }
 }
 return 0;
}
int print(char * p[],int n)
{
 for(int i=0;i<n;i++){
  cout<<"排序后输出显示:"<<endl;
  cout<<p[i]<<endl;
 }
 return 0;
}
//如果将cout输出改为*p[i],则只输出字符串的第一个字符
5.system函数---Mr.Zhang
system函数 是可以调用一些DOS命令,比如system("cls");//清屏,等于在DOS上使用cls命令.写可执行文件路径,
可以运行它·system()函数用于向操作系统传递控制台命令行,以WINDOWS系统为例,
通过system()函数执行命令和在DOS窗口中执行命令的效果是一样的,所以只要在运行窗口中可以使用的命令都可以用SYSTEM()传递,
但要注意的是输入斜线时要输入两个,以名C语言当作转义字符处理。
6.typedef 经典应用---Mr.Zhang
编程者定义变量时往往是直接定义,这带来一个坏处就是看程序的人无法了解其变量含义,如何解决这一问题呢?看下例你就明白了
#include "stdafx.h"
#include "iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
 typedef int Height;
 typedef int Weight;
 Height x=10;
 Weight y=23;
 cout<<x<<endl;
 cout<<y<<endl;
 return 0;
}
7.struct和class之间的区别---Mr.Zhang
struct在c中不能定义函数,而c++中可以定义函数。
struct在c++中定义函数是缺省情况为public,而class缺省情况在c++中是private。
8.函数重载:---Mr.Zhang
函数重载条件:
函数参数类型或者函数参数个数不同才能构成函数重载。
不能重载情况之特例:
一、int fac(){}
    void fac(){}
二、int fac(int a ,int b=5){}
    int fac(int a){}
即带有缺省值的类似二的函数是不能重载的
9.虚拟函数---Mr.Zhang
一、先调用虚基类的构造函数,再调用非虚基类的构造函数
二、同一层次包含多个虚基类,按照它们被继承先后次序调用,如果某个虚基类构造函数已经被调用,则不被再调用。
三、若虚基类有非基类派生而来,想调用虚基类的基类构造函数,在调用虚基类的构造函数。
#include"stdafx.h"
#include"iostream"
using namespace std;
class A{
 int a;
public:
 A(){
 cout<<"A"<<endl;
 }
};
class C{
public:
 C(){
  cout<<"C"<<endl;
 }
};
class B:public C{
public:
 B(){
 cout<<"B"<<endl;
 }
};
class B1:virtual public  A ,virtual public  B{
public:
 B1(){
 cout<<"B1"<<endl;
 }
};
class B2:public A ,virtual public B{
public :
 B2(){
 cout<<"B2"<<endl;
 }
};

class D:public B1,public B2{
public:
 D(){
 cout<<"D"<<endl;
 }
}; 
int main(){
  D d;
  return 0;
}

运行结果:
A
C
B
B1
A
B2
D
请按任意键继续. . .


10.条件编译---Mr.Zhang
#ifndef x //if not define的简写
#define x
...
#endif
这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等.实际上确切的说这应该是预处理功能中三种
(宏定义,文件包含和条件编译)中的一种----条件编译。 C语言在对程序进行编译时,会先根据预处理命令进行“预处理”。
C语言编译系统包括预处理,编译和链接等部分。
#ifndef x //先测试x是否被宏定义过
#define x
程序段 1 //如果x没有被宏定义过,定义x,并编译程序段 1
#endif
程序段 2 //如果x已经定义过了则编译程序段2的语句,“忽视”程序段 1。
条件指示符#ifndef 的最主要目的是防止头文件的重复包含和编译。了解:条件编译当然也可以用条件语句来实现。
但是用条件语句将会对整个源程序进行编译,生成的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目标程序较短。
如果条件选择的程序段很长,采用条件编译的方法是十分必要的。

作用:在c语言中,对同一个变量或者函数进行多次声明是不会报错的。所以如果h文件里只是进行了声明工作,即使不使用# ifndef宏定义,
一个c文件多次包含同一个h文件也不会报错。使用#ifndef可以避免下面这种错误:如果在h文件中定义了全局变量,一个c文件包含同一个h文件多次,如果不加#ifndef宏定义,
会出现变量重复定义的错误;如果加了#ifndef,则不会出现这种错.


11.用system()打开文件(如txt)---Mr.Zhang

system("notepad d://t//u.txt")   //打开记事本

system("call d://t//u.txt")    //打开记事本

system("d://t//u.txt")        //打开记事本

 

以上只能打开记事本,打开其它文件需要:
system("start  * ")

收获:cmd中执行以上命令也是可以打开的
12.魔鬼细节--fgetc---Mr.Zhang
对于fgetc函数api是这样定义的:
语法:
  #include <stdio.h>
  int fgetc( FILE *stream );
fgetc()函数返回来自stream(流)中的下一个字符,如果到达文件尾或者发生错误时返回EOF.
其实原因全在于EOF,EOF返回值是-1,字符都是以ASCII码形式来工作的,我们可以理解为在字符形式下ASCII也可以识别EOF,这样EOF的字符形式有可能会看成字符,
产生二义性,而无法找到文件结束!因此定义成int型,返回的字符再转换成int型。
13.魔鬼细节---fseek---Mr.Zhang
fseek API定义:
语法:
  #include <stdio.h>
  int fseek( FILE *stream, long offset, int origin );
函数fseek()为给出的流设置位置数据. origin的值应该是下列值其中之一(在stdio.h中定义):
名称     说明
SEEK_SET 从文件的开始处开始搜索
SEEK_CUR 从当前位置开始搜索
SEEK_END 从文件的结束处开始搜索
fseek()成功时返回0,失败时返回非零. 你可以使用fseek()移动超过一个文件,但是不能在开始处之前. 使用fseek()清除关联到流的EOF标记.

函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere
(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。
如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。

结论:fseek返回值为:0或非0。  改变的是文件指针的指向位置。

14..魔鬼细节---ftell---Mr.Zhang
ftell API定义:
语法:
  #include <stdio.h>
  long ftell( FILE *stream );
  ftell()函数返回stream(流)当前的文件位置,如果发生错误返回-1.

注意:文件的起始位置是0。

你可能感兴趣的:(编程,C语言,c语言日志)