8.1
程序不得違反標准C語法和約束,不得超出實現的轉換限制
0232 十六進制轉義序列的值在“unsigned char”類型中無法表示。
int ia = '\x4142'; /* Message 0232 */
char 字符常量只有1個Byte大小(不考慮寬字符常量),‘\x4142’ = 16706, 超過范圍了。 0-255
十六進制轉義序列的值不得超過unsigned char中可表示的值的范圍.
char 類型用於存儲字母和標點符號之類的字符,但是在技術實現上char卻是整數類型,這是因為char類型實際存儲的是整數而不是字符
char grade = 'A' ;
char grade = 65; // 這是一種不好的編程風格
令人奇怪的是,C將字符常量視為int類型而非char類型
0233 八進制轉義序列的值不得超過unsigned char中可表示的值的范圍
/*PRQA S 3123,3211,3408,3610,3625,3628 ++*/ int ia = '\432'; /* Message 0233 */
0322 'for'語句聲明中使用的非法存儲類說明符
for循環的第一項可以聲明變量,但是只有'auto' and 'register'兩個存儲類說明符可以用, 'static', 'extern' or 'typedef'不可用
void foo(void) { for (static int i = 0; i < 10; ++i) /* Message 0322 */ { } }
https://blog.csdn.net/wfreehorse/article/details/60762579
0338 八進制和16進制轉義字符值超過‘unsigned char’ ‘wchar_t’所表示的范圍
char *s = "\400"; /* Message 0338 */ // \400 = 256 ; \377 = 255 // "\400" 是一個字符數組,s[0] = '\400' , s[1] = '\0'
0422 調用函數是傳參的個數 小於 函數原型指定的參數個數
int foo(int a, int b); void test(int x) { int ret; ret = foo(x); /* Message 0422 */ }
0423 調用函數是傳參的個數 大於 函數原型指定的參數個數
0426 被調用函數返回類型不完整
typedef struct S T1; extern T1 s; extern T1 foo1(int n); void foo2(int n) { /* struct S 還沒定義 */ s = foo1(n); /* Message 0426 */ } struct S {int a; int b;}; /* struct S is now a complete type */ void foo3(int n) { s = foo1(n); /* OK - return type is now complete */ }
0427 該對象已被用作函數或函數指針標識符。
void foo(void) { int r; int name; r = name(); /* Message 0427 */ }
0429 一個函數的參數是算術類型,但是傳進去的參數不是算術類型。
extern void foo(int p); struct ST1 { int si; char sbuf[10];}; union UN1 { int ui; int uj;}; extern struct ST1 st1a; extern union UN1 un1a; extern int *pi; extern int gi; extern void test(void) { foo(gi); /* OK */ foo(pi); /* Message 0429 */ foo(&gi); /* Message 0429 */ foo(st1a); /* Message 0429 */ foo(un1a); /* Message 0429 */ }
0430 跟上一條類似,函數傳參類型不匹配。
0431 函數參數指向受限類型(Function argument points to a more heavily qualified type)。
不能把const type * 傳給函數參數原型為 type*
不能把volatile type * 傳給函數參數原型為 type*
反之可以,可以把 type * 傳給函數參數原型為 const type*
eg:
const int *a;
int *b;
b = a; // wrong
a = b; // right 指針a指向的內容不能變(不能通過指針a改變,可以通過其他指針改變),但是指針a這個地址可以變。
#include<stdio.h> int main() { const int a[3] = { 1 , 2,3 }; const int *c = a; int b[3] = { 4,5,6 }; //a = b; c = b; //c[1] = 3; // wrong //b = c;// wrong printf("%d\n", c[1]); }
extern void fi(int * pi); extern void fci(const int * pci); extern void fvi(volatile int * pvi); extern void fcvi(const volatile int * pcvi); extern int *pi; extern const int *pci; extern volatile int *pvi; extern const volatile int *pcvi; void test(void) { fi(pi); /* */ fi(pci); /* Message 0431 */ fi(pvi); /* Message 0431 */ fi(pcvi); /* Message 0431 */ fci(pi); /* */ fci(pci); /* */ fci(pvi); /* Message 0431 */ fci(pcvi); /* Message 0431 */ fvi(pi); /* */ fvi(pci); /* Message 0431 */ fvi(pvi); /* */ fvi(pcvi); /* Message 0431 */ fcvi(pi); /* */ fcvi(pci); /* */ fcvi(pvi); /* */ fcvi(pcvi); /* */ }
0432 函數參數不是兼容的指針類型
struct ST1 { int si; char sbuf[10];}; union UN1 { int ui; int uj;}; extern struct ST1 st1a; extern union UN1 un1a; extern char *pc; extern char **ppc; extern char gc; extern char cbuf[10]; extern unsigned char *puc; extern void foo(char * ptp); void test(void) { foo(pc); /* OK */ foo(st1a); /* Message 0432 */ foo(un1a); /* Message 0432 */ foo(gc); /* Message 0432 */ foo(ppc); /* Message 0432 */ foo(cbuf); /* OK */ foo(puc); /* Message 0432 'char' and 'unsigned char' (or 'signed char') are distinct types*/ }
0446 ++ / -- 操作數必須是標量
struct ST {int a; int b;}; union UN {char c[4]; int x;}; extern struct ST st; extern union UN un; void foo(void) { st++; /* Message 0446 */ un++; /* Message 0446 */ }
0447 ++ / -- 的操作數必須是可修改的對象。
extern int x[10]; extern const int y; void foo(void) { ++x; /* Message 0447 */ ++y; /* Message 0447 */ }
0448 ++ / -- 的操作數不能是指向未知大小的對象的指針。
extern struct TAG *pc; extern int (*pa)[]; extern void *pv; void foo (void) { ++pc; /* Message 0448 */ ++pv; /* Message 0448 */ ++pa; /* Message 0448 */ }
0449 ++ / -- 的操作數不能是函數指針
extern void (*fn_ptr)(void); void foo (void) { ++fn_ptr; /* Message 0449 */ }
0450 數組類型表達式不能 類型轉換
類型轉換的操作數必須是標量類型(scalar type) (A basic type, enumeration type or pointer type)
(The type char
, the signed
and unsigned
integer types, and the floating types)
struct ST { int ai[3]; }; extern struct ST sf(void); extern struct ST sta; extern int ibuf[10]; void foo(void) { char *pc; pc = (char *)ibuf; /* OK - ibuf decays to type pointer to int */ pc = (char *)(sta.ai); /* OK - sta.ai decays to type pointer to int */ pc = (char *)(sf().ai); /* Message 0450 and also 0481 */ pc = (char *)sta; /* Message 0481 - sta is not of scalar type */ }
0452 指針下標索引未知大小的對象。
extern struct ST *gx; /* The size of struct ST is unknown */ void foo(struct ST *px) { *gx = px[2]; /* Message 0452 */ }
0454 取地址符& 不能應用於 使用'register'聲明的對象
void foo (void) { register int a; int *pa; pa = &a; /* Message 0454 */ }
The address-of operator '&' cannot be applied to an object declared with the 'register' storage-class specifier.
The C language defines five storage-class specifiers: static, extern, auto, register
and typedef
0456 該表達式沒有地址 - “&”只能應用於左值或函數指示符。
運算符&只能應用於函數指示符或左值,不能指定 位字段 且不能 指定 寄存器存儲類說明符 聲明的對象。
extern int g; extern void func(int x); void foo(void) { int *pi; void (*pvf)(int x); pi = &g; /* Operand of & is an lvalue */ pvf = &func; /* Operand of & is a function designator */ pvf = func; /* & is optional on a function designator */ /* See ISO-C90 6.2.2.1 */ pi = &(g + 1); /* Message 0456 */ }
0457 取地址符不能應用在位字段
位bit 可以占據 一個字節byte中的部分或者全部, & 根據字節讀地址,不能精確到字節中某一位的地址。
struct flags { unsigned int hi:1; unsigned int lo:1; unsigned int ins:1; unsigned int ovr:1; }; int main(void) { struct flags f; int *ip; unsigned int i; f.hi = 0; f.lo = 0; f.ins = 0; f.ovr = 0; ip = &(f.hi); /* Message 0457 */ ip = &f.lo; /* Message 0457 */ i = f.ins; return 0; }
https://blog.csdn.net/huasir_hit/article/details/75201126
有些信息在存儲時,並不需要占用一個完整的字節, 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省存儲空間,並使處理簡便,C語言又提供了一種數據結構,稱為“位域”或“位段”。所謂“位域”是把一個字節中的二進位划分為幾個不同的區域,並說明每個區域的位數。每個域有一個域名,允許在程序中按域名進行操作。 這樣就可以把幾
個不同的對象用一個字節的二進制位域來表示。
一、位域的定義和位域變量的說明位域定義與結構定義相仿,其形式為:
struct 位域結構名
{ 位域列表 };
其中位域列表的形式為: 類型說明符 位域名:位域長度
https://www.runoob.com/cprogramming/c-bit-fields.html.
#include <stdio.h> #include <string.h> /* 定義簡單的結構 */ struct { unsigned int widthValidated; unsigned int heightValidated; } status1; /* 定義位域結構 */ struct { unsigned int widthValidated : 1; unsigned int heightValidated : 1; } status2; int main( ) { printf( "Memory size occupied by status1 : %d\n", sizeof(status1)); printf( "Memory size occupied by status2 : %d\n", sizeof(status2)); return 0; }
/*當上面的代碼被編譯和執行時,它會產生下列結果:*/ Memory size occupied by status1 : 8 Memory size occupied by status2 : 4
/* 位域聲明 在結構內聲明位域的形式如下: */ struct { type [member_name] : width ; }; 0457 取地址符不能應用在位字段
0482 Expressions may only be cast to 'void' or scalar types.
typedef struct ST { int a; } T; typedef void (FUNC)(void); int bar(void); void foo(int n) { T t; t = (T)n; /* Message 0482 - attempting to cast to struct type */ (FUNC)n; /* Message 0482 - attempting to cast to function type */ (void)bar(); /* OK */ }
0483 指向未知大小的對象的指針不能是加法運算符的操作數。
當進行任何一種指針的算術運算時,必須要知道指針指向對象的大小,例如,指針 加1,指針的值不是增加1,增加的是指向對象類型的大小。
extern struct ST *ps; extern void *pv; void foo(int n) { ps = ps + n; /* Message 483 */ pv = pv + n; /* Message 483 */ }
0546 枚舉類型定義不完整
enum ETAG ex; /* Message 0546 */ void foo(void) { }