您的位置:首页 > 编程语言

C编程细节(4)

2016-09-27 15:57 120 查看
1.短路径法则。&&操作,如果右边的结果为假则直接得出结果为假。||操作,如果右边结果为真则直接得出结果为真。此过程提升了效率,但是若是在右边出现赋值操作,则可能会跳过此表达式,所以应去避免。

2.表达式的运算顺序与操作符的优先级、结合性以及操作符是否控制执行顺序有关。运算符的优先级从高到底:单目,算术,移位,关系,逻辑,三目,复合赋值,逗号。几类中,其内部也有不同的优先级别。

3.一些变量的生命周期,作用域。静态变量,局部静态变量。首先这两个变量都是存储在数据段中的,静态变量是文件作用域,不可被文件外的引用。局部变量作用于局部区域,但是即使调用函数结束,它也不会消失,可以在下次函数引用中继续使用上次的值。

4.移位操作。移位操作分为左移和右移,而右移分为逻辑右移和算术右移,不同的机器或许采用不同的移位方式。逻辑右移是在左边补零,而算术右移是在左边补符号位值。

5.整型数移位中的隐式类型转换。

 例:表达式a = (~a^b<<1)>>1;的汇编代码如下:

       movsx       eax,byte ptr [a]  //将a移动到32位寄存器,隐式类型提升

       not         eax               //对a做非

       movsx       ecx,byte ptr   //将b隐式类型提升为32位

       shl         ecx,1             //b右移一位放置ecx中

       xor         eax,ecx            //eax与ecx做异或放置到eax中

       sar         eax,1              //将eax中的值右移一位  

       mov         byte ptr [a],al       //将eax中的低八位al中的值拿出

 

6.首元素地址的代表意义:数组中首元素有时代表整个数组,有时代表首个元素。

(结构体名的意义,数组的意义,)   

结构体大小问题:

当结构体中的最宽类型大小 <= 默认对其大小时,则以最宽对齐

          当最宽类型大小 >  默认对齐标准时,则以默认对齐

Windows下默认大小8Byte

Linux   下默认大小4Byte

7.const问题。

int  const  *i; 与 const  int  *i;作用一样,即该变量只能解引用,不能被修改。

int  *const  i;表示该指针变量中的值不能修改,即指向的空间不能变。

    

8.二维数组的传参问题:二维数组传参传的是数组指针,通过给数组指针做自增运算,使得其能在列级别上变化,再通过解引用做运算在行级别上变化。

传参的时候一定要传递列数,函数可通过形参传递过去,因为在子函数中,传递过来的数组名只是一个指针,不能sizeof出整个数组的大小。或者在最后一行设置特殊符合约定进行结束,防止越界。

一维数组不能直接使用数组指针,除非强制转化类型。

两种类型的实际效果一样,通过指针自增,都是前进一行。

void tra(int arr[][5]);
int main()
{
int arr[4][5]={{0},{1},{2},{3}};
tra(arr);
return 0;
}
void tra(int arr[][5])
{
printf(“%d”,sizeof(arr));
}

void tra(int (*arr)[5]);
int main()
{
int arr[7][5]={{0},{1},{2},{3},{7}};
tra(arr);
return 0;
}


10.柔性数组

struct soft_array
{
int len;
int array[];
}soft;
printf("%d",sizeof(soft));


11.命令行参数,利用主函数的参数,int main(int argc, char **argv,char **envp)。第一个参数是参数的数目,第二个是指针数组,将输入的命令参数视为字符串,并将其地址存储在指针数组中。通过argc来控制次数对argv经行解引用操作。envp是计算机的环境变量。

12.指针数组,数组中的元素是指针,指针类型可以为整型指针,函数指针等。

13.数组指针,指向数组的指针。

14.函数指针,指向函数的指针。

15.二维数组传参,必须传递列。

16.strtok函数是将一个字符串按分割符分割成单词逐个向外返回其地址的。其使用方法:取第一个单词时strtok(strings, blank),接下来的字符串是strtok(NULL,blank)。判断当接收的指针变为NULL时结束。for循环示例: for (token = strtok(strings, whitespace); token!=NULL; token = strtok(NULL,whitespace))。

17.归纳总结常用函数。  

几种函数的理解:fgets,strstr,strcmp,等。其返回值代表意义,其形参的个数、排列,其实现的方法。                                                               

  [b]char *strtok( char *
strToken, const char *strDelimit );  //return a pointer to the next token found instrToken. They returnNULL when no more tokens are found.

char *fgets( char *string, int n, FILE *stream );    // returnsstring.NULL is returned to indicate an error or an end-of-file condition

int fputs( const char *string, FILE *stream );    //returns a nonnegative value if it is successful. On an error,fputs returnsEOF

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );  //fread returns the number of full items actually read

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );     //fwrite returns the number of full items actually
written, which may be less than count if an error occurs. Also, if an error occurs, the file-position indicator cannot be determined.

int fgetc( FILE *stream );      //Read a character from a stream ,fgetc return the character read as anint or returnEOF 

int fputc( int c, FILE *stream );         //returns the character written.fputc a return value ofEOF indicates an error.

18.回调函数:用一个函数指针作为函数参数传递给其他函数,后者将回调用户函数。

void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

//Performs a quick sort。借用函数库提供的函数模板来实现快速排序,只需编写比较函数,再利用函数指针将其引入到该函数中去,则可实现。

void *bsearch( const void *key, const void *base, size_t num, size_t width, int ( __cdecl *compare ) ( const void *elem1, const void *elem2 ) );   

//bsearch returns a pointer to an occurrence of key in the array pointed to bybase. Ifkey is not found, the function returnsNULL. If the array is not in ascending sort order or contains duplicate records with identical
keys, the result is unpredictable.

19.

for(int i=0; i<100 ;i++)
{
int sum=0;  static int sum2 = 0;
sum += 1;  sum2 += 1;
}


其中的sum不会被反复的申请、初始化,只是申请一次,初始化一次。它是区域性变量,可见性只是在此区域中,在其函数中此语句块后可通过间接访问进行访问。

两者的打印值,sum每一次都会被int sum=0刷新为0,但是static int sum2=0只会被执行一次,其不断累积,直到退出时值为100
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息