小結1
void真正發揮的作用在於:對函式返回的限定;對函式引數的限定。
float *p1;
int *p2;
p1 = p2;
其中p1 = p2語句會編譯出錯,提示“ ‘=’:cannot convert from 'int *' to 'float *' ",需要改為:
p1 = (float *)p2;
然而void *則不同,任何型別的指標都可以直接賦值給它,無需進行強制型別轉換:
void *p1;
int *p2;
p1 = p2;
但是下面語句卻是錯的:
void *p1;
int *p2;
p2 = p1;
void* 需要進行強制型別轉換再賦給其他指標。
按照ANSI標準,不能對void指標進行演算法操作:
void * pvoid;
pvoid ++; //ANSI:錯誤
pvoid += 1; //ANSI:錯誤
但在GNU編譯器中是正確的
因此在實際的程式設計中,為符合ANSI標準,並提高程式的可移植性,我們可以這樣編寫實現同樣功能的程式碼:
void * pvoid;
(char *)pvoid++;
(char *)pvoid += 1;
柔性陣列
typedef struct st_type
{
int i;
int a[0];
}type_a;
有些編譯器會報錯無法編譯,可以改成:
typedef struct st_type
{
int i;
int a[];
}type_a;
這樣我們就可以定義一個可以變長的結構體,用sizeof(type_a)得到的只有4,就是sizeof(i)=sizeof(int)。0個元素的陣列沒有佔用空間,而後我們可以進行變長操作。通過如下表達式給結構體分配記憶體:
type_a * p = (type_a *) malloc (sizeof(type_a ) + 100 * sizeof(int));
用p->item[n]就能簡單地訪問可變長元素。但是再用sizeof(*p)測試結構體的大小,發現還是4。
測大小端
int checkSystem()
{
union check
{
int i;
char ch;
}c;
c.i = 1;
return (c.ch == 1);
}
在X86系統下,以下程式輸出值為多少?
#include <stdio.h>
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf ("%x, %x",ptr1[-1],*ptr2);
return 0;
}
輸出值為5,2。
typedef struct student
{
//code
}Stu_st,* Stu_pst;
1、struct studebt stu1 和 Stu_st stu1 沒有區別
2、struct studebt *stu2、Stu_pst stu2 和 Stu_st *stu2 沒有區別
3、const Stu_pst stu3; const修飾的是stu3這個指標
4、Stu_pst const stu4; const修飾的是stu4這個指標
字元在記憶體中是以ASCAII碼儲存的,所以字元常量可以與整形常量或變數進行運算,
如:'A' + 1
按位異或操作可以實現不用第三個臨時變數交換兩個變數的值: a ^= b; b ^= a; a ^= b;